1
\$\begingroup\$

As you can see I have to populate the ViewModel with the List of Tags so that the dropdown can have all the options for the user to select. And I have to do this 2 times for the Create Action and 2 times for the Edit action.

[Authorize]
public ActionResult Create()
{
 var tags = from i in _articleService.GetAllTags()
 select new SelectListItem {Text = i.Name, Value = i.ID.ToString()};
 var model = new CreateArticleViewModel {Tags = tags};
 return View(model);
}
[HttpPost, Authorize]
public ActionResult Create(CreateArticleViewModel model)
{
 if (ModelState.IsValid)
 {
 try
 {
 var currentUser = _userService.GetByUserName(User.Identity.Name);
 var tagIds = model.TagIds.Select(int.Parse);
 var article = _articleService.Create(currentUser, model.Title, model.Body, tagIds);
 return RedirectToAction("ViewArticle", new { id = article.ID });
 }
 catch (Exception ex)
 {
 ModelState.AddModelError("Error", ex.Message);
 }
 }
 var tags = from i in _articleService.GetAllTags()
 select new SelectListItem { Text = i.Name, Value = i.ID.ToString() };
 model.Tags = tags;
 return View(model);
}
[Authorize]
public ActionResult Edit(int id)
{
 var article = _articleService.GetById(id);
 var tags = from tag in _articleService.GetAllTags().ToList()
 select new SelectListItem { Text = tag.Name, Value = tag.ID.ToString(), Selected = article.HasTag(tag)};
 var model = new CreateArticleViewModel {Title=article.Title, Body = article.Body, Tags = tags };
 return View(model);
}
[HttpPost, Authorize]
public ActionResult Edit(CreateArticleViewModel model)
{
 if (ModelState.IsValid)
 {
 try
 {
 //handle article update
 }
 catch (Exception ex)
 {
 //Add ModelState error 
 }
 }
 var tags = from tag in _articleService.GetAllTags().ToList()
 select new SelectListItem { Text = tag.Name, Value = tag.ID.ToString(), Selected = article.HasTag(tag)};
 model.Tags= tags;
 return View(model);
}

Is there a better way?

svick
24.5k4 gold badges53 silver badges89 bronze badges
asked Feb 24, 2012 at 15:37
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

You could refactor out your tagging into a helper method, as below:

[Authorize]
public ActionResult Create()
{
 var model = new CreateArticleViewModel {};
 TagModel (model, _ => false);
 return View(model);
}
[HttpPost, Authorize]
public ActionResult Create(CreateArticleViewModel model)
{
 if (ModelState.IsValid)
 {
 try
 {
 var currentUser = _userService.GetByUserName(User.Identity.Name);
 var tagIds = model.TagIds.Select(int.Parse);
 var article = _articleService.Create(currentUser, model.Title, model.Body, tagIds);
 return RedirectToAction("ViewArticle", new { id = article.ID });
 }
 catch (Exception ex)
 {
 ModelState.AddModelError("Error", ex.Message);
 }
 }
 TagModel (model, _ => false);
 return View(model);
}
[Authorize]
public ActionResult Edit(int id)
{
 var article = _articleService.GetById(id);
 var model = new CreateArticleViewModel {Title=article.Title, Body = article.Body};
 TagModel (model, tag => article.HasTag (tag));
 return View(model);
}
[HttpPost, Authorize]
public ActionResult Edit(CreateArticleViewModel model)
{
 if (ModelState.IsValid)
 {
 try
 {
 //handle article update
 }
 catch (Exception ex)
 {
 //Add ModelState error 
 }
 }
 TagModel (model, tag => article.HasTag (tag));
 return View(model);
}
private void TagModel (CreateArgicleViewModel model, Predicate<Tag> isSelected)
{
 var tags = from tag in _articleService.GetAllTags()
 select new SelectListItem { Text = tag.Name, Value = tag.ID.ToString(), Selected = isSelected(tag)};
 model.Tags= tags;
}
answered Feb 24, 2012 at 18:30
\$\endgroup\$
1
\$\begingroup\$

Recently I've been reading a great series of blog posts by Ayende Rahien discussing how we can limit abstractions in a code base and how to implement a very simple infrastructure to make an abstraction for code reuse. Take a look at one of the posts of these series here. You can find the rest of them on his blog.

answered Feb 25, 2012 at 21:43
\$\endgroup\$
2
  • \$\begingroup\$ great series of blogposts... I dont see how it relates to my question though. \$\endgroup\$ Commented Feb 27, 2012 at 20:22
  • \$\begingroup\$ You can use Query abstraction to run a predefined query to get all the tags \$\endgroup\$ Commented Feb 27, 2012 at 21:25

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.