Posting GridView Data to MVC Controller
Visual Studio 2013 provides a unified development environment for ASP.NET Web
Forms and ASP.NET MVC applications. This unified environment is called as One
ASP.NET. What it means for developers is that a single project can use Web
Forms, MVC controllers and Web API. While using all these pieces of ASP.NET
inside a single application there can be a couple of possibilities:
- An existing Web Forms project wants to use MVC for new modules /
functionality. The new modules are totally independent from the existing Web
Forms.
- The new modules want to interact with existing Web Forms. The existing
Web Forms want to send and receive data to and from the MVC controllers
The former case is quite straightforward. All you need to do is add new MVC
controllers to the same Web Forms project and add a few lines of code in the
Global.asax as suggested by the readme file generated by the Scaffolding dialog.
The second case, however, requires some thought. The remainder of this article
illustrates how Web Forms can send data to MVC controllers.
Suppose you have a Web Form consisting of a GridView. And the GridView
displays a list of Customers from the Northwind database as shown below:
Upon clicking the Edit button you wish to send the Customer data - CustomerID,
CompanyName, ContactName and Country - to an MVC controller. The MVC controller
then renders a View that allows you to edit that Customer. This View is shown
below:
You can edit the Customer information and hit the Update button to save the
data. The View submits the data back to the MVC controller which saves it to the
database and redirects the control to the Web Form. The Web Form then displays a
success message as shown below:
Let's see how this can be accomplished using "One ASP.NET" of Visual Studio
2013.
Begin by creating a new ASP.NET project based on the Empty project template
and check the "Web Forms" checkbox under "Add folder and core references for".
This will create a new project targeted at Web Forms development. Then add a
new Web Form - WebForm1.aspx - in the project. Add a GridView control on the Web
Form and configure it to show CustomerID, CompanyName, ContactName and Country
columns of the Northwind database. You can either use SQL Data Source control or
Entity Framework to deal with the database operations.
Then add a TemplateField to the GridView. Place a Button server control
inside this template and set its PostBackUrl property to /home/edit. The
following markup shows this TemplateField.
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="Button1"
runat="server"
PostBackUrl="/home/edit"
Text="Edit" />
</ItemTemplate>
</asp:TemplateField>
The PostBackUrl of the Button control specifies a server side resource to
which the form will be submitted when the button under consideration is clicked.
In this case you set the PostBackUrl to an MVC action method named edit residing
in the Home controller. You will add this controller and its action in a minute.
Then add a HiddenField server control below the GridView. You can't submit
the GridView data to the MVC controller directly because GridiView is just a
table and form submission will carry this data as a part of the ViewState - not
easily accessible for our processing. That's why this hidden form field is
required. Its value will be set through jQuery code as you will see shortly.
<asp:HiddenField ID="DataToMVC" runat="server" />
Add a <script> reference to the jQuery library and also add a <script> block
in the head section of the Web Form. Then add the following code into the
<script> block:
<script src="Scripts/jquery-1.10.2.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("input:submit").click(function (evt) {
var data = {};
data.CustomerID = $(evt.target).closest("tr").children("td:eq(0)").html();
data.CompanyName = $(evt.target).closest("tr").children("td:eq(1)").html();
data.ContactName = $(evt.target).closest("tr").children("td:eq(2)").html();
data.Country = $(evt.target).closest("tr").children("td:eq(3)").html();
$("#DataToMVC").val(JSON.stringify(data));
});
});
</script>
The above script consists of a ready() handler. The ready() handler wires a
click event handler to all the submit buttons from the Web Form. In this case
all Edit buttons will be selected by the input:submit jQuery selector. The click
event handler creates a JavaScript object and sets its four properties -
CustomerID, CompanyName, ContactName and Country - to the values from a GridView
row. Notice how the Customer details are retrieved. The closest() method grabs
the reference of a table row that houses the Edit button. Then using children()
collection you access the individual GridView cells. The html() method will
return the data inside the GridView cells.
Once created the JSON stringified version of the data JavaScript object is
assigned to the hidden form field added earlier. Since Edit button is posting
the form to an MVC controller, the MVC controller can access this hidden form
field and read the Customer data.
Now, add Controllers folder inside the project, right click on it and add a
new MVC controller using Add Scaffold dialog.
Name the newly added controller as Home. Then add two action methods - Edit()
and Update() - to the Home controller. These methods are shown below:
public ActionResult Edit()
{
string jsonData = Request.Form["DataToMVC"];
Customer obj = JsonConvert.DeserializeObject<Customer>(jsonData);
//do something with data if required
return View(obj);
}
public void Update(Customer obj)
{
NorthwindEntities db = new NorthwindEntities();
Customer existing = db.Customers.Find(obj.CustomerID);
existing.CompanyName = obj.CompanyName;
existing.ContactName = obj.ContactName;
existing.Country = obj.Country;
db.SaveChanges();
Response.Redirect("/webform1.aspx?customerid=" + obj.CustomerID);
}
The Edit() action method is important because it reads the JSON stringified
data sent from the Web Form. Inside, it reads the hidden field (DataToMVC) and
stores its value in a string variable. Then Json.NET library is used to
deserialize this JSON string into Customer object. Notice that in the Web Forms
we created the data JavaScript object such that it matches the structure of the
Customer entity class. The Customer object thus read is passed to the Edit view
as its model.
The Edit view submits its data to the Update() action method and Update()
action receives it as a Customer object. Inside, it simply updates an existing
Customer and saves the changes to the database. Once the data is updated it
redirects the control to WebForm1.aspx and passes the CustomerID in the query
string. The WebForm1.aspx can use this query string to display a success message
to the user.
Next, add Edit view to the project and key in the markup shown below:
@model WebFormPostingMVC.Models.Customer
...
<body>
@using(Html.BeginForm("Update","Home",FormMethod.Post))
{
@Html.LabelFor(c=>c.CustomerID)
<br />
@Html.TextBoxFor(c=>c.CustomerID)
<br />
@Html.LabelFor(c=>c.CompanyName)
<br />
@Html.TextBoxFor(c => c.CompanyName)
<br />
@Html.LabelFor(c=>c.ContactName)
<br />
@Html.TextBoxFor(c => c.ContactName)
<br />
@Html.LabelFor(c=>c.Country)
<br />
@Html.TextBoxFor(c => c.Country)
<br /><br />
<input type="submit" value="Update" />
}
</body>
</html>
The Edit view is straightforward and submits its data to the Update action
method created earlier.
As the final step, add the following code to the Page_Load event handler of
WebForm1.aspx.
protected void Page_Load(object sender, EventArgs e)
{
if(!string.IsNullOrEmpty(Request.QueryString["customerid"]))
{
Label1.Text = "Customer " +
Request.QueryString["customerid"] +
" updated successfully!";
}
}
The Page_Load event handler simply checks whether CustomerID has been passed
in the query string or not. If CustomerID is available it displays a message in
a Label control informing the user about the success of update operation.
The following figure shows the final project structure of this application.
That's it! Run the Web Form, try clicking on the Edit button of any record
and see if the MVC view displays the data for editing purpose. Also, check if
clicking on the Update button of the Edit view takes the control back to the Web
Form.