如何避免ViewBag(或ViewData)支持模型?

时间:2011-03-04 11:24:25

标签: c# asp.net-mvc asp.net-mvc-3

这是一个非常简单的例子,但它足以证明我的问题。我需要将模型传递给我的用户将更新的视图,但视图还需要一些其他数据来创建下拉列表或提供其他信息。

根据我在下面的代码,我想避免使用ViewBag / ViewData ,所以我会以某种方式合并QuestionListPasswordLength (引入一个多余的示例场景)到ChangeSecurityQuestionModel或者创建一个新的ViewModel或其他一些对象?

[Authorize]
public ActionResult ChangeSecurityQuestion() {
  var user = Membership.GetUser();
  if (user != null) {
    var model = new ChangeSecurityQuestionModel() {
      PasswordQuestion = user.PasswordQuestion
    };
    ViewBag.QuestionList = new SelectList(membershipRepository.GetSecurityQuestionList(), "Question", "Question");
    ViewBag.PasswordLength = MembershipService.MinPasswordLength;
    return View(model);
  }

  // user not found
  return RedirectToAction("Index");
}

[Authorize]
[HttpPost]
public ActionResult ChangeSecurityQuestion(ChangeSecurityQuestionModel model) {
  if (ModelState.IsValid) {
    var user = Membership.GetUser();
    if (user != null) {
      if (user.ChangePasswordQuestionAndAnswer(model.Password, model.PasswordQuestion, model.PasswordAnswer)) {
        return View("ChangeQuestionSuccess");
      } else {
        ModelState.AddModelError("", "The password is incorrect.");
      }
    }
  }

  // If we got this far, something failed, redisplay form
  ViewBag.QuestionList = new SelectList(membershipRepository.GetSecurityQuestionList(), "Question", "Question");
  ViewBag.PasswordLength = MembershipService.MinPasswordLength;
  return View(model);
}

3 个答案:

答案 0 :(得分:6)

为什么不将QuestionList和PasswordLength放在ChangeSecurityQuestionModel

var model = new ChangeSecurityQuestionModel() {
      PasswordQuestion = user.PasswordQuestion,
      QuestionList = new SelectList(membershipRepository.GetSecurityQuestionList(), "Question", "Question"),
      PasswordLength = MembershipService.MinPasswordLength;
    };

答案 1 :(得分:4)

您可以将QuestionListPasswordLength属性添加到ChangeSecurityQuestionModel视图模型中。然后:

[Authorize]
public ActionResult ChangeSecurityQuestion() {
    var user = Membership.GetUser();
    if (user != null) {
        var model = new ChangeSecurityQuestionModel() {
            PasswordQuestion = user.PasswordQuestion,
            QuestionList = new SelectList(membershipRepository.GetSecurityQuestionList(), "Question", "Question"),
            PasswordLength = MembershipService.MinPasswordLength
        };
        return View(model);
    }
    // user not found
    return RedirectToAction("Index");
}

[Authorize]
[HttpPost]
public ActionResult ChangeSecurityQuestion(ChangeSecurityQuestionModel model) {
    if (ModelState.IsValid) {
        var user = Membership.GetUser();
        if (user != null) {
            if (user.ChangePasswordQuestionAndAnswer(model.Password, model.PasswordQuestion, model.PasswordAnswer)) {
                return View("ChangeQuestionSuccess");
            } else {
                ModelState.AddModelError("", "The password is incorrect.");
            }
        }
    }
    // If we got this far, something failed, redisplay form
    model.QuestionList = new SelectList(membershipRepository.GetSecurityQuestionList(), "Question", "Question");
    model.PasswordLength = MembershipService.MinPasswordLength;
    return View(model);
}

答案 2 :(得分:4)

反复出现“do-I-use ViewState或继续添加模型”问题的一种替代方法是为HtmlHelper创建扩展方法:

public static class HtmlExtensions
{
     public static MvcHtmlString SecurityQuestionDropDown(this HtmlHelper helper)
     {
          return helper.DropDownList(....,new SelectList(membershipRepository.GetSecurityQuestionList(), "Question", "Question"));
     }
}