2017-03-15 152 views
2

我正在使用NopCommerce v3.80。默認情況下,登錄和註冊視圖是不同的。我需要合併它們而不改變很多代碼,所以我在Login.cshtml中調用了@{ RenderAction("Register"); }ASP.NET mvc RenderAction登錄和註冊查看

我也從註冊視圖中刪除了佈局(Layout = "~/Views/Shared/_ColumnsOne.cshtml";)。

問題出在驗證錯誤,如「電子郵件ID已存在!」它來到了寄存器視圖。我需要在登錄視圖中顯示驗證或錯誤消息。但登錄視圖只接受登錄模型。

請看看我的代碼:

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 - 註冊方法

public ActionResult Register(RegisterModel model){ 
    // Lot of code 
    if (success){ 
    // lot of code 
     return RedirectToRoute("RegisterResult"); 
    } 
    foreach (var error in registrationResult.Errors) 
     ModelState.AddModelError("", error); 
    PrepareCustomerRegisterModel(model, true, customerAttributesXml); 
    return View(model); 

} 

更新:我檢查how to work with two forms in a single view,但它不會幫助我,因爲我無法用新的模式創建選項去。

更新2:我也嘗試了新的模型創建選項,其中涵蓋了登錄和註冊模型,但我仍然得到相同的結果。

+0

那是因爲你在你的註冊行動返回查看(模型)。您可以在註冊操作中返回部分視圖。或者更好的做法是將你的註冊作爲局部視圖。 – jomsk1e

+0

@ jomsk1e我試圖返回部分視圖。但沒有變化。 –

+0

返回部分視圖並更改您的表單以在您的登錄操作上發佈,而不是在此行上註冊:'使用(Html.BeginForm(「Register」,「Customer」,FormMethod.Post))' – jomsk1e

回答

1

謝謝大家的努力。我不得不創建新的模型,幷包裹在裏面的兩個模型註冊和登錄。

它看起來像how to work with two forms in a single view幫了我很多。

但是,我發佈一個新手的完整解決方案。

CustomerController:

加載頁面

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

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

雷吉斯之三:

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

     } 

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

然後創建了兩個局部視圖 - _LoginModel.cshtml_registerModel.cshtml。在意見我只加一個額外的行

_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> 
    } 

,最後登錄頁面

登錄。 cshtml

更換註冊按鈕(左面板)

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

和登錄形式

@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

如果沒有更重要的代碼更改,那麼您嘗試執行的操作並不是真的可行,那麼您已經完成了操作,因爲驗證範圍僅限於您正在處理的特定模型。

也許我能想到的最簡單有效的解決方案,就是將Login視圖的模型更改爲其他兩個模型的包裝。

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

這應該解決大多數你遇到的問題,雖然驗證信息必須在你的結構被正確定位:

ModelState.AddModelError("Register", error); 
:在你的代碼

ModelState.AddModelError("", error); 

被替換

+0

我作爲return語句寫什麼在POST方法的註冊?我應該返回PartialView(「_ Register」,registerModel)還是返回View(「Index」,authenticationModel)? –

+0

如果你沒有額外的代碼來處理這些Ajax動作,View(「Index」,authenticationModel)應該是正確的方法,因爲你正在處理頁面重新加載。 –

1

除了將模型組合成視圖模型以使用包含兩種模型的應用程序(例如,您可能應該在這種情況下應該這樣做)之外,便宜且容易的選項是檢測錯誤並將其傳遞給ba ck作爲視圖屬性。然後在前端可以檢查該屬性是否爲空,如果是,則顯示錯誤消息。

儘管你應該創建一個視圖模型,但其他一切都更像是一個創可貼解決方案。

0

您可以將登錄和註冊模型合併到一個全新的模型中,以便驗證可以適用於所需的模型。