簡體   English   中英

由於ModelState在PartialView之后丟失,因此未顯示MVC 3驗證消息

[英]MVC 3 validation messages not shown due ModelState lost after PartialView

我有一個MVC 3項目,我有一個視圖LoginRegister,其中包含2個視圖,其中包含用於登錄和預注冊的表單。 問題是在錯誤地完成預注冊表單並使用PartialView(“LoginRegister”,loginRegisterViewModel)后,由於ModelState丟失而未顯示驗證消息。 在閱讀下一段之前,最好跳到CODE

調試PartialView(“LoginRegister”,loginRegisterViewModel)並進入以下@Html.ErrorMessageFor(model => model.Email)的PreRegister視圖。 ModelState不包含電子郵件密鑰(見下文),因此不顯示錯誤消息。

    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);
    }

這是由於在viewData new ViewDataDictionary()時清除了viewData

@{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應該可以在您的視圖中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM