I have a simple MVC 2 blog that I'm building as I learn. My edit page has title, body, date, enabled and tags. The tags is where my problem comes in. I have a Tags table and a Posts table and tags are associated to a post through the PostTag table. I have my linq model setup properly and I even have the Add HttpPost action working.
My problem is with the Edit view, where I want to remove tags that were on the Post object model at load time, and update them with the tags that are on the Post object model when it is HttpPost-ed. How can I accomplish this since my Model is complex? My Edit view:
[HttpPost, Authorize, ValidateInput(false)]
public ActionResult Edit(int id, FormCollection form)
{
Post p = repo.GetPost(id);
if (p == null)
return View("NotFound");
if (ModelState.IsValid)
{
try
{
UpdateModel(p);
//Do something here to update the model p.TagList child model
// the p.TagList object is not updated through UpdateModel
repo.Save();
return RedirectToAction("Post", "Blog", new { id = p.PostID });
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
ModelState.AddRuleViolations(p.GetRuleViolations());
}
}
return View(p);
}
What I've done to help translate tags on the Edit page to a collection of objects is through a TagListString object which just serializes each tag name separated by a space. When I post it back, I can easily reconstruct the TagList object by iterating through my TagListString - but it doesn't get updated!
I've tried several ways of updating the TagList model. Looping through and doing repo.Delete() on the existing ones and then adding then reconstructing and adding the new ones. I've tried just creating a new collection and adding the new Tag objects that way. Here are a few of the things I've tried.
public void UpdateTagList(System.Data.Linq.EntitySet<PostTag> postTags, string tagListString)
{
db.PostTags.DeleteAllOnSubmit(postTags);
db.PostTags.InsertAllOnSubmit(GenerateTagListFromString(tagListString, postTags.SingleOrDefault().Post));
}
private System.Data.Linq.EntitySet<PostTag> GenerateTagListFromString(string tagListString, Post post)
{
System.Data.Linq.EntitySet<PostTag> tagList = new System.Data.Linq.EntitySet<PostTag>();
foreach (var t in tagListString.Trim().Split(' '))
{
//look for this tag name in cache (MvcApplication.AllTags)
Tag found = MvcApplication.AllTags.SingleOrDefault(item => item.TagName.Trim().ToLower() == t.Trim().ToLower());
//new PostTag for this new Post
PostTag pt = new PostTag();
pt.Tag = found ?? new Tag() { TagName = t };
pt.Post = post;
tagList.Add(pt);
}
return tagList;
}