这里有一个方法,它是一个登录方法,如果用户名和密码不正确,就会添加ModelError。
[HttpPost]
public ActionResult Login(LoginClass model, string ReturnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(ReturnUrl) && ReturnUrl.Length > 1 && ReturnUrl.StartsWith("/")
&& !ReturnUrl.StartsWith("//") && !ReturnUrl.StartsWith("/\\"))
{
return Redirect(ReturnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect");
}
}
return RedirectToAction("Index", "Home");
}我的问题是如何将ModelError显示到视图Index.cshtml中?
发布于 2016-04-07 10:44:57
..。如何将ModelError显示到视图Index.cshtml中?
显示错误信息
我最初假设您想要重定向到主页(HomeController action Index),这是基于您在Login操作底部对return RedirectToAction("Index", "Home");的调用。现在我在想,这可能是流中的一个错误,您实际上是在尝试向用户显示错误消息而不进行重定向,并且只有在一切顺利的情况下才需要重定向。,如果是这样的话,只需阅读这个部分,然后跳过关于如何在RedirectToAction调用中持久化模型状态的其余部分。如果出现故障,只需调用View而不是RedirectToAction。
[HttpPost]
public ActionResult Login(LoginClass model, string ReturnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(ReturnUrl) && ReturnUrl.Length > 1 && ReturnUrl.StartsWith("/")
&& !ReturnUrl.StartsWith("//") && !ReturnUrl.StartsWith("/\\"))
{
return Redirect(ReturnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect");
}
}
return View(model); // goes back to the login view with the existing model and validation error
// return RedirectToAction("Index", "Home");
}Login.cshtml在某个地方包括以下内容
@Html.ValidationSummary()使用RedirectToAction
它不能工作的原因是在执行ViewData时丢失了包含验证消息的RedirectToAction。有几种解决方案。
ViewData保存在RedirectToAction上,然后恢复它。ModelState中指定的新操作执行后,才能持久化该RedirectToAction,然后将其与RedirectToAction合并。持久化ViewData
在大多数情况下,这可以很好地工作,但是如果您重定向到操作(在本例中是HomeController上的索引)有自己的ViewData,则可能会导致问题。
LoginController.cs
// simplified code to just show the relevant parts to reproduce the problem/solution
[HttpPost]
public ActionResult Login(LoginClass model, string ReturnUrl)
{
// ... some other code
ModelState.AddModelError("", "The user name or password provided is incorrect");
// ... some other code
if (!ModelState.IsValid)
TempData["ViewData"] = ViewData;
return RedirectToAction("Index", "Home");
}HomeController.cs
public ActionResult Index()
{
if (TempData["ViewData"] != null)
{
// restore the ViewData
ViewData = (ViewDataDictionary)TempData["ViewData"];
}
return View();
}Home\Index.cshtml
@Html.ValidationSummary()合并ModelState
这将是我推荐的方法,因为您定义了如何在自定义ActionFilter属性上执行一次,然后应用到希望它发生的位置。您也可以将此代码直接放入控制器中,但一旦需要对多个控制器执行此操作,就会违反do原则。
这里的方法是,如果TempData尚未包含"ModelState"键,则将模型状态写入"ModelState"。如果已经有一个关键的礼物,这意味着当前的请求刚刚写到它,我们可以从中读取,并将其与我们现有的模型状态合并。这将防止代码在现在合并ViewState或ModelState时无意地覆盖ModelState或ModelState。只有当有多个RedirectToActions选择写到ModelState时,我才能看到这个错误,但我不认为这是一个可能的场景。
ModelStateMergeFilterAttribute.cs
public class ModelStateMergeFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
// write to the temp data if there is modelstate BUT there is no tempdata key
// this will allow it to be merged later on redirect
if (filterContext.Controller.TempData["ModelState"] == null && filterContext.Controller.ViewData.ModelState != null)
{
filterContext.Controller.TempData["ModelState"] = filterContext.Controller.ViewData.ModelState;
}
// if there is tempdata (from the previous action) AND its not the same instance as the current model state THEN merge it with the current model
else if (filterContext.Controller.TempData["ModelState"] != null && !filterContext.Controller.ViewData.ModelState.Equals(filterContext.Controller.TempData["ModelState"]))
{
filterContext.Controller.ViewData.ModelState.Merge((ModelStateDictionary)filterContext.Controller.TempData["ModelState"]);
}
base.OnActionExecuted(filterContext);
}
}LoginController.cs
// simplified the code to just show the relevant parts
[HttpPost]
[ModelStateMergeFilter]
public ActionResult Login(LoginClass model, string ReturnUrl)
{
ModelState.AddModelError("", "The user name or password provided is incorrect");
return RedirectToAction("Index", "Home");
}HomeController.cs
[ModelStateMergeFilter]
public ActionResult Index()
{
return View();
}Home\Index.cshtml
@Html.ValidationSummary()参考文献
以下是一些参考资料,其中也详细介绍了这些方法。我还依赖于前面这些答案中的一些输入作为我上面的答案。
发布于 2016-04-04 14:04:02
如果您正在使用MVC,则可以使用验证摘要。
@Html.ValidationSummary();https://msdn.microsoft.com/en-CA/library/dd5c6s6h%28v=vs.71%29.aspx
另外,将您的模型传递回您的视图:
return RedirectToAction("Index", "Home", model);https://stackoverflow.com/questions/36404788
复制相似问题