服务器端验证期间MVC表单丢失值

时间:2015-10-23 20:58:47

标签: asp.net-mvc asp.net-mvc-5

我正在将现有网站从WebForms迁移到MVC 5.

我有一个联系我们页面,其中有客户端验证,用于检查字段是否已完成等。但是,我正在使用BotDetect CAPTCHA,它具有服务器端验证,以检查CAPTCHA是否已正确完成。

如果我输入正确的CAPTCHA,则所有操作均按预期工作 - 将发送电子邮件并在电子邮件中显示所有表单字段。

如果我输入错误的CAPTCHA,我应该返回到表单,将显示无效CAPTCHA的错误消息,但仍应填写所有其他字段。

但是,这种情况并没有发生。表单字段丢失。我猜这是因为模型正在重新生成。我没想到的是如何让我的ActionResult放弃执行任何操作并保留表单内容。

我的观点:

@using BotDetect.Web.UI.Mvc;
@model Framework.Models.FrameworkModel

@section Styles {
    <link href="@BotDetect.Web.CaptchaUrls.Absolute.LayoutStyleSheetUrl" rel="stylesheet" type="text/css" />
}

<h1>@Html.Raw(Model.Page.Heading)</h1>
<div class="main-container">
    @if (string.IsNullOrWhiteSpace(ViewBag.Status))
    {
        @Html.Raw(Model.Page.Body)
        <br />
        <fieldset id="ContactFields" class="contact-fields">
            <ol>
                <li>
                    <label id="FullNameLabel" labelfor="FullName">@Resources.Contact.FullNameLabel</label>
                    @Html.TextBoxFor(model => model.Contact.FullName, new { @id = "FullName", @Name = "FullName", @class = "standard-textbox", @autocompletetype = "DisplayName", @data_validation_required = Resources.Contact.FullNameValidationErrorMessage})
                </li>
                <li>
                    <label id="EmailLabel" labelfor="Email">@Resources.Contact.EmailLabel</label>
                    @Html.TextBoxFor(model => model.Contact.Email, new { @id = "Email", @Name = "Email", @class = "standard-textbox", @autocompletetype = "Email", @data_validation_required = Resources.Contact.EmailValidationErrorMessage, @data_validation_format = Resources.Contact.EmailValidationErrorMessageFormat })
                </li>
                <li>
                    <label id="SubjectLabel" labelfor="Subject">@Resources.Contact.SubjectLabel</label>
                    @Html.TextBoxFor(model => model.Contact.Subject, new { @id = "Subject", @Name = "Subject", @class = "standard-textbox", @data_validation_required = Resources.Contact.SubjectValidationErrorMessage })
                </li>
                <li>
                    <label id="MessageLabel" labelfor="Message">@Resources.Contact.MessageLabel</label>
                    @Html.TextAreaFor(model => model.Contact.Message, new { @id = "Message", @Name = "Message", @class = "multiline-textbox", @rows = 5, @data_validation_required = Resources.Contact.MessageValidationErrorMessage })
                </li>
                <li>
                    <div class="captcha-control">
                        <br />
                        @{ MvcCaptcha captcha = Model.CaptchaHelper.GenerateCaptcha(); }
                        @Html.Captcha(captcha)
                        <br />
                        @Html.TextBox("CaptchaCode", "", new { @id = "CaptchaCode", @Name = "CaptchaCode", @class = "captcha-code short-textbox", @data_validation_required = Resources.Captcha.CaptchaValidationErrorMessage })
                        @Html.ValidationMessage("CaptchaCode")
                    </div>
                    <br />
                    <button id="SendButton" type="submit" class="send-button">@Resources.Contact.SendButton</button>
            </ol>
        </fieldset>
    }
    else
    {
        <span class="alert">@Html.Raw(ViewBag.Status)</span>
    }
</div>

@section Scripts {
    @Scripts.RenderFormat("<script type=\"text/javascript\" src=\"{0}\" defer=\"defer\"></script>", "~/bundles/scripts/contact")
}

我的控制器的一部分(删除了对无关操作的调用):

using Framework.App_Code.ViewRendering;
using Framework.Models;
using System.Web.Mvc;
using BotDetect.Web.UI.Mvc;

namespace Framework.Controllers
{
    public class PagesController : AsyncController
    {
        [HttpGet]
        [ActionName("Contact")]
        public ActionResult Contact()
        {
            Contact viewRendering = new Contact();
            return View(viewRendering.GenerateModel());
        }

        [HttpPost]
        [ActionName("Contact")]
        [AllowAnonymous]
        [CaptchaValidation("CaptchaCode", "Captcha")]
        public ActionResult ContactPost(ContactModel contactModel, bool captchaValid)
        {
            Contact viewRendering = new Contact();
            if (ModelState.IsValid)
            {
                contactModel.IPAddress = Request.ServerVariables["REMOTE_ADDR"].Trim();
                ViewBag.Status = viewRendering.SendMail(contactModel);
            }
            MvcCaptcha.ResetCaptcha("Captcha");
            return View(viewRendering.GenerateModel());
        }

    }
}

1 个答案:

答案 0 :(得分:4)

当您返回到无效案例中的视图时,请将模型传回以重新显示(即!ModelState.IsValid执行此操作时...)

return View(contactModel); // this is the one that was submitted