Bulk Data Update with ASP.NET MVC
Recently I was doing some R&D with ASP.NET MVC. During that I was mimicking the Create a Movie Database Application in 15 Minutes with ASP.NET MVC (C#) tutorial, which is a nice ice-breaker tutorial. Once I was done with it, I was thinking of some more complex real-life scenarios. As a business application developer, I came across a scenario when I need to implement a bulk update operation through a Web interface. I hate it simply !!!!! Binding the data, then iterate through the Grid, do a lot of FindControl….
So I thought let’s try the same scenario with ASP.NET MVC….
There is a nice blog by Phil Haack on the topic, which is for Beta version, and the same approach doesn’t quite work with the released version. After tumbling few times finally I got the thing working, and my first observation is that, I am loving it !!!!!, it’s short, much more simple and the best part no more auto generated garbage HTML markups. The result is much more cleaner in terms of HTML. Though some you may not agree with me, but I always thought of having greater control over the HTML generation, the way it was with Classic ASP. Webforms doesn’t provide that, specially if you are using a Gridview.
So let’s look at the page.
It’s a simple UI, where I can update multiple book records, and then hit the “Save Changes” button to commit all the changes.
First I have created a database with a simple table, and the generated the ASP.NET Entity class, to perform the CRUD operation, though in this example i will only use the Update operation. I am not going into details on How to use the Entity framework.
I have used the HomeController’s Index() method to create a View with all the Movie records, in a tabular format. The code looks like,
1: BookStoreEntities _db = new BookStoreEntities();
2: public ActionResult Index()
3: {
4: return View(_db.BookDetails.ToList());
5: }
The View looks like this:
<form action="/Home/Index" method="post">
<table>
<tr>
<th>
BookID
</th>
<th>
Title
</th>
<th>
Author
</th>
<th>
Publication
</th>
</tr>
<% int i = 0; %>
<% foreach (var item in Model) { %>
<tr>
<td>
<%= Html.Encode(item.BookID) %>
<input type="hidden" name='<%= "BookList[" + i + "].BookID" %>' value='<%=item.BookID %>' />
</td>
<td>
<input type="text" name='<%= "BookList[" + i + "].Title" %>' value='<%=item.Title %>' />
</td>
<td>
<input type="text" name='<%= "BookList[" + i + "].Author" %>' value='<%=item.Author %>' />
</td>
<td>
<input type="text" name='<%= "BookList[" + i + "].Publication" %>' value='<%=item.Publication %>' />
</td>
</tr>
<% i++; %>
<% } %>
</table>
<p>
<input type="submit" value="Save Changes" />
</p>
</form>
The View is simple enough, though there are few important points here, without which the Save won’t work. First of all I have added a <form> tag, with method=”post”, and action="/Home/Index". Now the most important point, name='<%= "BookList[" + i + "].BookID" %>' , here i is a Zero-based index, which will be used to recreate the List of books upon submission.
Next I have added another Index method to handle the Form submission.
1: [AcceptVerbs(HttpVerbs.Post)]
2: public ActionResult Index(IList<BookDetails> BookList)
3: {
4: if (ModelState.IsValid)
5: {
6: foreach (BookDetails editedBook in BookList)
7: {
8: var tempBook = (from book in _db.BookDetails
9: where book.BookID == editedBook.BookID
10: select book).First();
11:
12: _db.ApplyPropertyChanges(tempBook.EntityKey.EntitySetName, editedBook);
13: }
14: _db.SaveChanges();
15: return View(_db.BookDetails.ToList());
16: }
17: else
18: {
19: return View();
20: }
21: }
Also note that the name “BookList” is same as in the HomeController’s Index method’s parameter’s name.
I guess that’s it!!!! very simple and clean way to handle Bulk Update scenario.