2017-03-15 5 views
2

Ich arbeite an NopCommerce v3.80. Standardmäßig sind die Anmelde- und Registeransichten unterschiedlich. Ich musste sie zusammenführen, ohne viel Code zu ändern, also rief ich innerhalb von Login.cshtml @{ RenderAction("Register"); } an.ASP.NET mvc RenderAction Anmelden und Registrieren Views

Ich habe auch das Layout (Layout = "~/Views/Shared/_ColumnsOne.cshtml";) aus der Registeransicht entfernt.

Das Problem liegt vor, wenn ein Validierungsfehler wie 'Email Id exists!' kommt, es geht in die Registeransicht. Ich muss die Validierungs- oder Fehlermeldung in der Login-Ansicht anzeigen. Die Anmeldesicht akzeptiert jedoch nur das Anmeldemodell.

Bitte siehe mein Code:

Register.cshtml

@model RegisterModel 
@using Nop.Web.Models.Customer; 
@{ 
    //Layout = "~/Views/Shared/_ColumnsOne.cshtml"; 
} 

<!-- Registeration fields --> 

Login.cshtml

@model LoginModel 
@using Nop.Web.Models.Customer; 
@{ 
    Layout = "~/Views/Shared/_ColumnsOneTT.cshtml"; 
} 

@using (Html.BeginForm("Register", "Customer", FormMethod.Post)){ 
<div> 
@{ 
    Html.RenderAction("Register"); 
} 
<input type="submit" value="Submit"/> 
} 

CustomerController.cs - Registrieren Methode

UPDATE: Ich habe how to work with two forms in a single view aber es wird mir nicht helfen, da ich nicht mit neuer Modellerstellung Option gehen.

UPDATE 2: Ich habe auch mit der neuen Modellerstellungsoption versucht, die die Login- und Registermodelle abdeckt, aber ich bekomme immer noch das gleiche Ergebnis.

+0

es ist, weil Sie View (Modell) im Register Aktion zurückkehren. Sie können eine Teilansicht in Ihrer Aktion Registrieren zurückgeben. Oder noch besser machen Sie Ihre Registrierung als Teilansicht. – jomsk1e

+0

@ jomsk1e Ich habe versucht, Teilansicht zurückzugeben. aber keine Veränderung. –

+0

Teilansicht zurückgeben und das Formular so ändern, dass es auf Ihrer Login-Aktion posten statt auf dieser Zeile registrieren: 'using (Html.BeginForm (" Register "," Customer ", FormMethod.Post))' – jomsk1e

Antwort

1

Vielen Dank für Ihre Bemühungen.Ich musste ein neues Modell erstellen und die beiden Modelle Register und Login in das verpacken.

es sieht aus wie how to work with two forms in a single view hat mir sehr geholfen.

Allerdings posten ich komplette Lösung für einen Neuling.

CustomerController:

Laden der Seite

public ActionResult Login(bool? checkoutAsGuest) 
     { 
      var loginModel= new LoginModel(); 
      loginModel.UsernamesEnabled = _customerSettings.UsernamesEnabled; 
      loginModel.CheckoutAsGuest = checkoutAsGuest.GetValueOrDefault(); 
      loginModel.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnLoginPage; 

      var registerModel = new RegisterModel(); 
      PrepareCustomerRegisterModel(registerModel, false); 
      registerModel.Newsletter = _customerSettings.NewsletterTickedByDefault; 

      return View(new LoginRegisterModel { LoginModel = , RegisterModel = registerModel }); 
     } 

Anmeldung POST:

public ActionResult Login(LoginModel model, string returnUrl, bool captchaValid) 
     { 
     // Previous code as it is 
     // Important! I Added this new line - to handle validation problems 
     ModelState.Add("LoginValidation", null); 
     //If we got this far, something failed, redisplay form 
     model.UsernamesEnabled = _customerSettings.UsernamesEnabled; 
     model.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnLoginPage; 

     var registerModel = new RegisterModel(); 
     PrepareCustomerRegisterModel(registerModel, false); 
     //enable newsletter by default 
     registerModel.Newsletter = _customerSettings.NewsletterTickedByDefault; 

     return View(new LoginRegisterModel { LoginModel = model, RegisterModel = registerModel }); 
    } 

Regis ter:

public ActionResult Register() 
     { 
      //check whether registration is allowed 
      if (_customerSettings.UserRegistrationType == UserRegistrationType.Disabled) 
       return RedirectToRoute("RegisterResult", new { resultId = (int)UserRegistrationType.Disabled }); 

      var model = new RegisterModel(); 
      PrepareCustomerRegisterModel(model, false); 
      model.Newsletter = _customerSettings.NewsletterTickedByDefault; 

      var loginModel = new LoginModel(); 
      loginModel.UsernamesEnabled = _customerSettings.UsernamesEnabled; 
      loginModel.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnLoginPage; 

      return View("Login", new LoginRegisterModel { RegisterModel = model, LoginModel = loginModel }); 

     } 

Register POST:

public ActionResult Register(RegisterModel model, string returnUrl, bool captchaValid, FormCollection form) 
     { 
      // previous code as it is 
      // added this line to handle validations 

      ModelState.Add("RegisterValidation", null); 
      //If we got this far, something failed, redisplay form 
      PrepareCustomerRegisterModel(model, true, customerAttributesXml); 

      var loginModel = new LoginModel(); 
      loginModel.UsernamesEnabled = _customerSettings.UsernamesEnabled; 
      //loginModel.CheckoutAsGuest = checkoutAsGuest.GetValueOrDefault(); 
      loginModel.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnLoginPage; 

      return View("Login", new LoginRegisterModel { RegisterModel = model, LoginModel = loginModel }); 
     } 

erstellt dann zwei Teilansichten - _LoginModel.cshtml und _registerModel.cshtml. In den Ansichten habe ich nur eine zusätzliche Zeile

_LoginModel.cshtml:

if (!MvcHtmlString.IsNullOrEmpty(validationSummary) && ViewData.ModelState.ContainsKey("LoginValidation")) 
    { 
     <div class="message-error">@validationSummary</div> 
    } 

_RegisterModel.cshtml

@if (!MvcHtmlString.IsNullOrEmpty(validationSummary) && ViewData.ModelState.ContainsKey("RegisterValidation")) 
    { 
     <div class="message-error">@validationSummary</div> 
    } 

und schließlich, Login-Seite

Anmeldung. cshtml

ersetzt Register-Taste (links mit)

@using (Html.BeginForm("Register", "Customer", FormMethod.Post)){ 
<!-- divs and other elements --> 
    @Html.Partial("_RegisterModel", Model.RegisterModel) 
<!-- divs and other elements --> 
} 

und Login-Formular mit

@using (Html.BeginForm("Login", "Customer", new { returnUrl = Request.QueryString["returnUrl"] }, FormMethod.Post)) 
         { 
         <!-- divs and other elements --> 
         @Html.Partial("_LoginModel", Model.LoginModel) 
<!-- divs and other elements --> 
         } 
3

Was Sie zu tun versuchen, ist nicht wirklich machbar ohne wichtigere Codeänderungen, als Sie es bereits getan haben, da die Validierung auf das spezifische Modell ausgerichtet ist, das Sie behandeln.

Wahrscheinlich die einfachste effektive Lösung, die ich mir vorstellen kann, würde das Modell der Login-Ansicht ändern, um ein Wrapper um die anderen beiden Modelle zu sein.

public class AuthenticationModel { 
    public LoginModel Login {get;set;} 
    public RegisterModel Register {get;set;} 
    public AuthenticationModel (LoginModel lModel, RegisterModel rModel) { 
     Login = lModel; 
     Register = rModel; 
    } 
} 

Das meiste des Problems lösen sollten Sie haben, wenn die Überprüfungsmeldungen korrekt an Ihrer Struktur ausgerichtet werden müssten:

ModelState.AddModelError("", error); 

im Code erhält folgende Fassung:

ModelState.AddModelError("Register", error); 
+0

was schreibe ich als return statement bei POST-Methode von Register? Soll ich PartialView ("_ Register", registerModel) zurückgeben oder View ("Index", authenticationModel) zurückgeben? –

+0

Wenn Sie keinen zusätzlichen Code haben, um diese Aktionen mit ajax zu behandeln, sollte View ("Index", authenticationModel) der richtige Weg sein, da Sie mit einem Seiten-Reload zu tun haben. –

1

Abgesehen von der Kombination von Modellen in einem Ansichtsmodell, das beide Modelle umfasst (wie Sie wahrscheinlich in diesem Fall tun sollten), wäre eine billige und einfache Möglichkeit, den Fehler zu erkennen und ba zu übergeben ck als eine Viewbag-Eigenschaft. Dann können Sie am Frontend prüfen, ob diese Eigenschaft nicht null ist und eine Fehlermeldung anzeigen, wenn dies der Fall ist.

Sie sollten jedoch ein Viewmodel erstellen, alles andere ist eher eine Umgehungslösung.

0

Sie könnten die Anmelde- und Registriermodelle in eine brandneue Version zusammenführen, damit die Validierungen an das gewünschte Modell angepasst werden können.