Wednesday, 24 September 2014

Controllers in MVC application


In this article we will discuss about controllers. In previous article , we discussed that, the URL - http://localhost/MVCDemo/Home/Index will invoke Index() function of HomeControllerclass. So, the question is, where is this mapping defined. The mapping is defined in Global.asax. Notice that in Global.asax we have RegisterRoutes() method. 
RouteConfig.RegisterRoutes(RouteTable.Routes); 


Right click on this method, and select "Go to Definition". Notice the implementation of RegisterRoutes() method in RouteConfig class. This method has got a default route.
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

The following URL does not have id. This is not a problem because id is optional in the default route.
http://localhost/MVCDemo/Home/Index

Now pass id in the URL as shown below and press enter. Nothing happens.
http://localhost/MVCDemo/Home/Index/10

Change the Index() function in HomeController as shown below.
public string Index(string id)
{
    return "The value of Id = " + id;
}

Enter the following URL and press enter. We get the output as expected.
http://localhost/MVCDemo/Home/Index/10

In the following URL, 10 is the value for id parameter and we also have a query string"name".
http://localhost/MVCDemo/home/index/10?name=Pragim

Change the Index() function in HomeController as shown below, to read both the parameter values.
public string Index(string id, string name)
{
    return "The value of Id = " + id + " and Name = " + name;
}

Just like web forms, you can also use "Request.QueryString"
public string Index(string id)
{
    return "The value of Id = " + id + " and Name = " + Request.QueryString["name"];
} 


Creating first asp.net MVC application

In this article we will discuss about
1. Creating an asp.net mvc application

2. Understand how mvc request is processed as apposed to webform request 



Creating an mvc application:
1. Open visual studio
2. Click File > New Project
3. Select "Web" from "Installed Templates" section
4. Select ASP.NET MVC 4 Web Application
5. Set Name="MVCDemo"
6. Click OK
7. Select "Empty" template. Select "Razor" as the ViewEngine. There are 2 built in view engines - Razor and ASPX. Razor is preferred by most mvc developers. We will discuss about Razor view engine in detail in a later article.
8. At this point you should have an mvc application created.

Notice that in the solution explorer, you have several folders - Models, Views, Controllers etc. As the names suggest these folders are going to contain Models, Views, and Controllers. We will discuss about Models, Views, and Controllers in a later article.

Now let's add a controller to our project
1. Right Click on "Controllers" folder
2. Select Add > Controller
3. Set Controller Name = HomeController
4. Leave rest of the defaults and click "Add"

We should have HomeController.cs added to "Controllers" folder. 

At this point run the application by pressing CTRL+F5. Notice that you get an error as shown below.


To fix this error, we need to add a view with name, "Index". We will discuss about views in detail in next session. Let's fix it another way. The following is the function that is automatically added to HomeController class

public ActionResult Index()
{
    return View();

}

Change the return type of Index() function from "ActionResult" to "string", and return string "Hello from MVC Application" instead of View().


public string Index()
{
    return "Hello from MVC Application";

}

Run the application and notice that, the string is rendered on the screen. When you run the application, by default it is using built-in asp.net development server. Let's use IIS, to run the application instead of the built-in asp.net development server.
1. In the solution explorer, right click on the project and select "Properties"
2. Click on "Web" tab
3. Select "Use Local IIS Web Server" radio button
4. Notice that the Project Url is set to http://localhost/MVCDemo by default
5. Finally click on "Create Virtual Directory" button.



Run the application, and notice that the URL is "http://localhost/MVCDemo/"

Now change the URL to "http://localhost/MVCDemo/Home/index"

In the URL "Home" is the name of the controller and "Index" is the method within HomeController class. 

So the improtant point to understand is that the URL is mapped to a controller action method. Where as in web forms application, the URL is mapped to a physical file. For example, in a web application, if we have to display the same message.
1. We add a webform and in the Page_load() event include Response.Write("Hello from ASP.NET Web Forms Application");
2. We then access WebForm1.aspx as shown below
http://localhost/WebFormsApplication/WebForm1.aspx
3. The Page load event gets executed and the message string is displayed. 

Monday, 22 September 2014

Bulk Edit Update Multiple Rows in ASP.Net GridView using CheckBoxes

In this article I will explain how to edit and update multiple rows in ASP.Net GridView using CheckBoxes i.e. the Rows which are checked will become editable and user can update multiple rows on one single Update button click.


For this sample to work you will need to download the Microsoft Northwind database using the following link

Desingner Source Code :
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CS.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type = "text/css">
    input[type=text], select{background-color:#FFDFD2; border:1px solid #ccc}
    </style>
</head>
<body style = "font-family:Arial;font-size:10pt">
    <form id="form1" runat="server">
<asp:GridView ID="gvCustomers" runat="server" AutoGenerateColumns="false" OnRowDataBound = "OnRowDataBound" DataKeyNames = "CustomerId">
    <Columns>
        <asp:TemplateField>
            <HeaderTemplate>
                <asp:CheckBox ID = "chkAll" runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" />
            </HeaderTemplate>
            <ItemTemplate>
                <asp:CheckBox runat="server" AutoPostBack="true" OnCheckedChanged="OnCheckedChanged" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Contact Name" ItemStyle-Width = "150">
            <ItemTemplate>
                <asp:Label runat="server" Text='<%# Eval("ContactName") %>'></asp:Label>
                <asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("ContactName") %>' Visible="false"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Country" ItemStyle-Width = "150">
            <ItemTemplate>
                <asp:Label ID = "lblCountry" runat="server" Text='<%# Eval("Country") %>'></asp:Label>
                <asp:DropDownList ID="ddlCountries" runat="server" Visible = "false">
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<br />
<asp:Button ID="btnUpdate" runat="server" Text="Update" OnClick = "Update" Visible = "false"/>
    </form>
</body>
</html>

 Code Behind :
using System;
using System.Web.UI.WebControls;
using System.Data;
using System.Linq;
using System.Configuration;
using System.Data.SqlClient;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            this.BindGrid();
        }
    }
    private void BindGrid()
    {
        SqlCommand cmd = new SqlCommand("SELECT top 10 CustomerId, ContactName, Country FROM Customers");
        gvCustomers.DataSource = this.ExecuteQuery(cmd, "SELECT");
        gvCustomers.DataBind();
    }
    private DataTable ExecuteQuery(SqlCommand cmd, string action)
    {
        string conString = ConfigurationManager.ConnectionStrings["constring"].ConnectionString;
        using (SqlConnection con = new SqlConnection(conString))
        {
            cmd.Connection = con;
            switch (action)
            {
                case "SELECT":
                    using (SqlDataAdapter sda = new SqlDataAdapter())
                    {
                        sda.SelectCommand = cmd;
                        using (DataTable dt = new DataTable())
                        {
                            sda.Fill(dt);
                            return dt;
                        }
                    }
                case "UPDATE":
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();
                    break;
            }
            return null;
        }
    }

    protected void Update(object sender, EventArgs e)
    {
        foreach (GridViewRow row in gvCustomers.Rows)
        {
            if (row.RowType == DataControlRowType.DataRow)
            {
                bool isChecked = row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked;
                if (isChecked)
                {
                    SqlCommand cmd = new SqlCommand("UPDATE Customers SET ContactName = @ContactName, Country = @Country WHERE CustomerId = @CustomerId");
                    cmd.Parameters.AddWithValue("@ContactName", row.Cells[1].Controls.OfType<TextBox>().FirstOrDefault().Text);
                    cmd.Parameters.AddWithValue("@Country", row.Cells[2].Controls.OfType<DropDownList>().FirstOrDefault().SelectedItem.Value);
                    cmd.Parameters.AddWithValue("@CustomerId", gvCustomers.DataKeys[row.RowIndex].Value);
                    this.ExecuteQuery(cmd, "UPDATE");
                }
            }
        }
        btnUpdate.Visible = false;
        this.BindGrid();
    }
    protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            SqlCommand cmd = new SqlCommand("SELECT DISTINCT(Country) FROM Customers");
            DropDownList ddlCountries = (e.Row.FindControl("ddlCountries") as DropDownList);
            ddlCountries.DataSource = this.ExecuteQuery(cmd, "SELECT");
            ddlCountries.DataTextField = "Country";
            ddlCountries.DataValueField = "Country";
            ddlCountries.DataBind();
            string country = (e.Row.FindControl("lblCountry") as Label).Text;
            ddlCountries.Items.FindByValue(country).Selected = true;
        }
    }
    protected void OnCheckedChanged(object sender, EventArgs e)
    {
        bool isUpdateVisible = false;
        CheckBox chk = (sender as CheckBox);
        if (chk.ID == "chkAll")
        {
            foreach (GridViewRow row in gvCustomers.Rows)
            {
                if (row.RowType == DataControlRowType.DataRow)
                {
                    row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked = chk.Checked;
                }
            }
        }
        CheckBox chkAll = (gvCustomers.HeaderRow.FindControl("chkAll") as CheckBox);
        chkAll.Checked = true;
        foreach (GridViewRow row in gvCustomers.Rows)
        {
            if (row.RowType == DataControlRowType.DataRow)
            {
                bool isChecked = row.Cells[0].Controls.OfType<CheckBox>().FirstOrDefault().Checked;
                for (int i = 1; i < row.Cells.Count; i++)
                {
                    row.Cells[i].Controls.OfType<Label>().FirstOrDefault().Visible = !isChecked;
                    if (row.Cells[i].Controls.OfType<TextBox>().ToList().Count > 0)
                    {
                        row.Cells[i].Controls.OfType<TextBox>().FirstOrDefault().Visible = isChecked;
                    }
                    if (row.Cells[i].Controls.OfType<DropDownList>().ToList().Count > 0)
                    {
                        row.Cells[i].Controls.OfType<DropDownList>().FirstOrDefault().Visible = isChecked;
                    }
                    if (isChecked && !isUpdateVisible)
                    {
                        isUpdateVisible = true;
                    }
                    if (!isChecked )
                    {
                        chkAll.Checked = false;
                    }
                }
            }
        }
        btnUpdate.Visible = isUpdateVisible;
    }
}

Download Here


Ref-http://msdn.microsoft.com/en-us/library/aa992036.aspx