How do you correctly submit 2 identical forms individually from the same submission?

This is apparently a fairly common question that I saw here on stackoverflow, but no one seems to have the answer I'm looking for. I have 2 forms (standard user input and register form) that I would like to receive on the same view. It works correctly if everything goes well, but if they have a failure, and 2 unwanted events appear in the form:

  • Both forms are trying to verify, but only one has been completed.
  • The username is the same in both forms, so the data entered in one is populated in both.

I am not sure what I need to understand about validation in order to do this job correctly, and any help would be greatly appreciated.

Here is the code:

@{ ViewBag.Title = "Log On"; } <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> </script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> @{Html.RenderPartial("LogIn", (FortyEightHourPrint.Models.LogOnModel)ViewBag.LogInModel);} @{Html.RenderPartial("Register", (FortyEightHourPrint.Models.RegisterModel)ViewBag.RegisterModel);} 

and partial view of the register

 @using (Html.BeginForm("Register","Account")) { @Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.") <div> <fieldset> <legend>Account Information</legend> <div class="editor-label"> @Html.LabelFor((m => m.UserName)) </div> <div class="editor-field"> @Html.TextBoxFor(m => m.UserName) @Html.ValidationMessageFor(m => m.UserName) </div> <div class="editor-label"> @Html.LabelFor(m => m.Email) </div> <div class="editor-field"> @Html.TextBoxFor(m => m.Email) @Html.ValidationMessageFor(m => m.Email) </div> <div class="editor-label"> @Html.LabelFor(m => m.Password) </div> <div class="editor-field"> @Html.PasswordFor(m => m.Password) @Html.ValidationMessageFor(m => m.Password) </div> <div class="editor-label"> @Html.LabelFor(m => m.ConfirmPassword) </div> <div class="editor-field"> @Html.PasswordFor(m => m.ConfirmPassword) @Html.ValidationMessageFor(m => m.ConfirmPassword) </div> <p> <input type="submit" value="Register" /> </p> </fieldset> </div> } 

and login

  @using (Html.BeginForm("LogIn","Account")) { <div> <fieldset> <legend>Account Information</legend> <div class="editor-label"> @Html.LabelFor(m => m.UserName) </div> <div class="editor-field"> @Html.TextBoxFor(m => m.UserName) @Html.ValidationMessageFor(m => m.UserName) </div> <div class="editor-label"> @Html.LabelFor(m => m.Password) </div> <div class="editor-field"> @Html.PasswordFor(m => m.Password) @Html.ValidationMessageFor(m => m.Password) </div> <div class="editor-label"> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> <p> <input type="submit" value="Log On" /> </p> </fieldset> </div> } 

and, of course, the material that the controller performs.

  public ActionResult LogOn() { if ((bool)(ViewBag.OkToRedirect ?? false)) return Redirect(getReturnUrl(ViewBag.ReturnUrl)); return View(); } public PartialViewResult LogIn() { return PartialView(); } // // POST: /Account/LogIn [HttpPost] public ViewResult LogIn(LogOnModel model, string returnUrl) { ViewBag.OkToRedirect = false; if (ModelState.IsValid) { if (Membership.ValidateUser(model.UserName, model.Password)) { FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); ViewBag.OkToRedirect = true; } else { ModelState.AddModelError("", "The user name or password provided is incorrect."); } } ViewBag.LogInModel = model; ViewBag.ReturnUrl = returnUrl; return View("LogOn"); } public PartialViewResult Register() { return PartialView(); } // // POST: /Account/Register [HttpPost] public ViewResult Register(RegisterModel model, string returnUrl) { ViewBag.OkToRedirect = false; if (ModelState.IsValid) { // Attempt to register the user MembershipCreateStatus createStatus; Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus); if (createStatus == MembershipCreateStatus.Success) { FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */); ViewBag.OkToRedirect = true; } else { ModelState.AddModelError("", ErrorCodeToString(createStatus)); } } ViewBag.RegisterModel = model; ViewBag.ReturnUrl = returnUrl; return View("LogOn"); } 

Also, I'm new to mvc, so if anyone can suggest a better approach, I am all ears.

+4
source share
2 answers
  • Add these extension methods to some class:

     public static IDisposable BeginFieldPrefix<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, object>> expression) { return BeginFieldPrefix(html, (LambdaExpression) expression); } internal static IDisposable BeginFieldPrefix(this HtmlHelper html, LambdaExpression expression) { return BeginFieldPrefix(html, html.GetName(ExpressionHelper.GetExpressionText(expression))); } public static IDisposable BeginFieldPrefix(this HtmlHelper html, string fieldPrefix) { var templateInfo = html.ViewData.TemplateInfo; string oldFieldPrefix = templateInfo.HtmlFieldPrefix; templateInfo.HtmlFieldPrefix = fieldPrefix; return Disposable.Create(() => templateInfo.HtmlFieldPrefix = oldFieldPrefix); } public static string GetName<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) { return html.GetName(ExpressionHelper.GetExpressionText(expression)); } public static string GetName(this HtmlHelper html, string expression) { return html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression); } 

Disposable class is in the Rx Framework: http://msdn.microsoft.com/en-us/library/system.reactive.disposables.disposable(v=vs.103).aspx

  • Use the following code inside the BeginForm block to prefix all fields:

    @using (Html.BeginFieldPrefix ("LoginForm")) {...}

    @using (Html.BeginFieldPrefix ("RegisterForm")) {...}

  • Use the UpdateModel and TryUpdateModel , which allows you to specify a field prefix instead of implicit model updates (see http://msdn.microsoft.com/en-us/library/dd493137.aspx ).

+3
source

Recently, I ran into the same problem when validation is done in multiple forms, since they contain the same field names.

This post really helped me.

Hope this helps,

Matt

0
source

Source: https://habr.com/ru/post/1382710/


All Articles