2017-03-15 151 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

您可以将登录和注册模型合并到一个全新的模型中,以便验证可以适用于所需的模型。