我有一个MVC 3项目,我有一个视图LoginRegister,其中包含2个视图,其中包含用于登录和预注册的表单。问题是在错误地完成预注册表单并使用PartialView(“LoginRegister”,loginRegisterViewModel)后,由于ModelState丢失而未显示验证消息。在阅读下一段之前,最好跳到 CODE 。
调试PartialView(“LoginRegister”,loginRegisterViewModel)并进入以下@ Html.ErrorMessageFor(model => model.Email)的PreRegister视图。 ModelState不包含Email密钥(见下文),因此不显示错误消息。
private static MvcHtmlString ErrorMessageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string validationMessage, IDictionary<string, object> htmlAttributes)
{
string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName)) // ModelState contains no keys, e.g. Email not found and a null is returned
{
return null;
}
// code continues here to render error message
}
的ViewModels
LoginRegisterViewModel
namespace Site.ViewModels.Account
{
public class LoginRegisterViewModel
{
public bool IsDialog { get; set; }
public PreRegisterViewModel PreRegister { get; set; }
public QuickLoginViewModel QuickLogin { get; set; }
}
}
PreRegisterViewModel
using FluentValidation.Attributes;
using Site.ViewModels.Validators;
namespace Site.ViewModels.Account
{
[Validator(typeof(PreRegisterViewModelValidator))]
public class PreRegisterViewModel
{
public string Email { get; set; }
public string ConfirmEmail { get; set; }
}
}
视图
登录登录注册
@model Site.ViewModels.Account.LoginRegisterViewModel
@{
Layout = ViewBag.Layout;
}
<div id="loginReg" class="mod-loginReg">
<h2>Login and Registration</h2>
@{Html.RenderPartial("PreRegister", Model.PreRegister, new ViewDataDictionary());}
@{Html.RenderPartial("QuickLogin", Model.QuickLogin, new ViewDataDictionary());}
</div>
预注册
@using Site.Classes.MVC.Extensions;
@model Site.ViewModels.Account.PreRegisterViewModel
@using (Html.BeginForm("PreRegister", "Account", FormMethod.Post, new { @class = "form-errorContainer" }))
{
<div class="mod-loginReg-register">
<h3>Register</h3>
<p>Please enter your email address to register.<br /><br /></p>
<div class="mod-loginReg-form">
<div class="field-item">
@Html.LabelFor(model => model.Email)
@Html.TextBoxFor(model => model.Email, new { @maxlength = "255", @class = "Textbox required email" })
@Html.ErrorMessageFor(model => model.Email)
</div>
<div class="field-item">
@Html.LabelFor(model => model.ConfirmEmail)
@Html.TextBoxFor(model => model.ConfirmEmail, new { @maxlength = "255", @class = "Textbox required email" })
@Html.ErrorMessageFor(model => model.ConfirmEmail)
</div>
<div class="button-group">
@Html.Button("Register", "Register")
</div>
</div>
</div>
}
的AccountController
[RequireHttps]
public ActionResult LoginRegister(int showDialog)
{
var loginRegisterViewModel = new LoginRegisterViewModel();
if (showDialog == 1)
{
ViewBag.Layout = "~/layouts/structure/dialog.cshtml";
loginRegisterViewModel.IsDialog = true;
}
else
{
ViewBag.Layout = "~/layouts/structure/2column.cshtml";
}
return PartialView(loginRegisterViewModel);
}
[RequireHttps]
public ActionResult PreRegister()
{
return PartialView();
}
[HttpPost]
[RequireHttps]
public ActionResult PreRegister(PreRegisterViewModel model)
{
if (ModelState.IsValid)
{
return PartialView("PreRegisterComplete");
}
var loginRegisterViewModel = new LoginRegisterViewModel { PreRegister = model, QuickLogin = new QuickLoginViewModel() };
return PartialView("LoginRegister", loginRegisterViewModel);
}
答案 0 :(得分:3)
这是由于在调用viewData
时new ViewDataDictionary()
被清除所致。
@{Html.RenderPartial("PreRegister", Model.PreRegister, new ViewDataDictionary());}
@{Html.RenderPartial("QuickLogin", Model.QuickLogin, new ViewDataDictionary());}
根据MSDN ViewDataDictionary用于:
表示用于在控制器之间传递数据的容器 和观点。
我认为你有充分的理由这样做,否则你就不会麻烦地添加额外的参数。
如果您将其更改为:
@Html.RenderPartial("PreRegister", Model.PreRegister)
@Html.RenderPartial("QuickLogin", Model.QuickLogin)
控制器中构建的ModelState
应该可以在您的视图中使用。