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.

Home Screen

 

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.

Source Code

26 Comments

  • Thanks. It's very useful article!
    I have a question: How to add validation to the textbox for this bind method?

  • Alex:

    Let's say the list in your controller is "UpdatedList" and the textbox you want to validate is someting like . So in the ModelState you need to add the Validation error message with the same "Key" as the control, in this case your validation control would be something like :

    Also in the controller or you would do something like: ModelState.AddModelError("UpdatedList[" + i + "].Title", "Error Message"), where i is the counter.

    Hope it answers your question.

  • Simple and cool

  • Hi,
    I just tired your method in MVC 2 but it's not working quite right, I was wondering if you could help. What I'm doing is making some fields editable but others not. Now when I post back and look through the controller code in debug mode, the identifier for each object of the IList shows up, but the field that I had a textbox input shows the original value not the value that I entered in the textbox. I appreciate it if you could offer some advice on this.
    Thanks,
    Giancarlo

  • figured it out, amazing what typos can do to your code. :P

  • @Giancarlo

    Do you have example code for mvc2, or do the same as this work?

    Best regards,
    Jonas

  • This is helpful but what would be more helpful is to show how to add dropdown list and calendars bound to a row in a table

  • This is exactly what I was looking for. Why the standard MVC grids can't incorporate this feature is beyond me.

  • Thank you very much!!!. I've been looking for this for 2-3 weeks. Very nice article.

  • Thanks lot.

  • The article is really good,i have a question.How can we add a dropdown to this grid

  • this is nice articles. but i have a query regarding this..!
    for example i have a table with 5 column and 10 row. in view i display only 3 column value with all row. but when click update button, it set remainder 2 column's (which not display in view)value NULL, why?

    if i want to update only specific column value, than how it is possible. for database connectivity i used Entity Framework.

    Thanks

  • Your are a F**king Genius I love you man thank you soooooo much dude.

  • Actually no matter if someone doesn't understand then its up to other viewers that they will assist, so here it happens.

  • Any idea how to complete this using the razor view engine? Would much syntax have to be changed?

  • Its like you read my mind! You seem to know so much about this, like you wrote the book in it
    or something. I think that you could do with a few pics
    to drive the message home a little bit, but other than that, this is
    great blog. An excellent read. I'll definitely be back.

  • Does this example still apply to MVC4 Razor? I ask because this is the type of example I've been looking for but can't seem to get it to work in MVC4 Razor.

    Thanks!

  • This post is priceless. How can I find out more?

  • Nice blog! Is your theme custom made or did you download it from somewhere?
    A theme like yours with a few simple adjustements would
    really make my blog jump out. Please let me know where you got your design.

    Thank you

  • Great article! We are linking to this particularly great post
    on our website. Keep up the good writing.

  • When I initially commented I clicked the "Notify me when new comments are added" checkbox and
    now each time a comment is added I get four e-mails with the same
    comment. Is there any way you can remove people from that service?
    Many thanks!

  • Through the years they have got managed to help countless individuals
    correct the partnerships and also not happy interactions by
    obtaining back the love plus communicating how the partners shortage.

  • An additional wonderful gift is a paid holiday by the beach; book in advance to save
    funds. I know that you are obtaining tired of figuring out how
    can your ipad works aside from carrying out emails.

  • My spouse and I stumbled over here by a different website and thought I should check things out.
    I like what I see so now i'm following you. Look forward to looking at your web page for a second time.

  • My programmer is trying to convince me to move to .net from PHP.

    I have always disliked the idea because of the expenses. But he's tryiong none the less. I've been using WordPress on a variety of websites
    for about a year and am worried about switching to another platform.
    I have heard very good things about blogengine.net.

    Is there a way I can transfer all my wordpress
    posts into it? Any help would be greatly appreciated!

  • You actually make it seem so easy with your presentation but I find this topic to be
    really something which I think I would never understand.
    It seems too complicated and very broad for me.
    I'm looking forward for your next post, I'll try to get the hang
    of it!

Comments have been disabled for this content.