In my last posting I introduced how to implement CheckBoxList in ASP.NET MVC. Showing checkbox list is one part of the story. When user saves the form then we have to update also data that was represented by CheckBoxList. In this posting I will show you how to update event tags collection when user saves event.
Prerequisites
To get better idea what I’m doing and what is the system and code I am working on take a quick look at these blog posts I wrote previously:
I think these two postings will give you enough background even if you just go quickly through them.
Getting tags back from controller
CheckBoxList extension method did already something right – it outputs tags as checkboxes with same name. Now it is really up to MVC to catch the result and to transform it to something we can use. And MVC does it pretty well as we see from the following code.
[HttpPost]
public ActionResult Edit(Event evt, int[] tagIds)
{
// ...
}
Yes, we will get back ID-s of selected tags to tagIds array if we name our checkbox list as tagIds. Here the example call to CheckBoxList() method in my view.
@Html.Raw(Html.CheckBoxList("tagIds", Model.TagsSelection));
Updating tags collection
Now we have selected tag ID-s and it’s time to update event tags collection. If you think that you just clear the tags collection and add new set of tags there then you are wrong. Don’t forget that our objects are persisted by Entity Framework (or by some other mapper) and they track the state of object and its members.
To avoid non-necessary deletes and inserts we have to synchronize current tag set of event with new one that came from form. It really doesn’t matter in my case as my site will be small. Here’s the code that synchronizes tags (deletes tags that were not selected and adds the ones that user selected).
private void SetEventTags(Event evt, int[] tagIds)
{
var selectedTags = GetTagsByIds(tagIds);
var eventTags = evt.Tags.ToList();
foreach (var tag in eventTags)
if (!selectedTags.Contains(tag))
evt.Tags.Remove(tag);
foreach (var tag in selectedTags)
if (!eventTags.Contains(tag))
evt.Tags.Add(tag);
}
private IList<Tag> GetTagsByIds(int[] tagIds)
{
var selectedTags = new List<Tag>();
foreach (var tagId in tagIds)
{
var tag = db.Tags.Single(t => t.Id == tagId);
selectedTags.Add(tag);
}
return selectedTags;
}
And here’s the example of our controller action.
[HttpPost]
public ActionResult Edit(Event evt, int[] tagIds)
{
// ...
db.events.Attach(evt);
SetEventTags(evt, tagIds);
db.ObjectStateManager.ChangeObjectState(evt, EntityState.Modified);
db.SaveChanges();
return RedirectToAction("Index");
}
Conclusion
Now you know how to implement checkbox list in ASP.NET MVC and how to get data back from list. We saw that getting tags back from checkbox list was very easy. We just names checkbox list like parameter of save method and ASP.NET MVC was able to build tag ID-s array for us. We also saw how to add selected tags to event tags collection without deleting all tags and then adding selected ones back.
View Comments (2)
Fought with this for a while...your post saved me! Thanks!!
checkbox list concept is good in Asp.net,nice to sharing.