ASP.NET mvc RenderAction 登录并注册视图
ASP.NET mvc RenderAction Login And Register Views
我正在开发 NopCommerce v3.80。默认情况下,登录和注册视图是不同的。我需要在不更改太多代码的情况下合并它们,所以我在 Login.cshtml.
中调用了 @{ RenderAction("Register"); }
我还从注册视图中删除了布局 (Layout = "~/Views/Shared/_ColumnsOne.cshtml";
)。
问题是当像 'Email Id already Exists!' 这样的验证错误出现时,它会转到注册视图。我需要在登录视图上显示验证或错误消息。但登录视图仅接受登录模型。
请看我的代码:
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: 我也尝试了新的模型创建选项,它涵盖了登录和注册模型,但我仍然得到相同的结果。
如果没有比您已经完成的更重要的代码更改,您尝试做的事情实际上是不可行的,因为验证的范围仅限于您正在处理的特定模型。
可能是我能想到的最简单有效的解决方案,就是将登录视图的模型更改为其他两个模型的包装器。
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("", error);
在您的代码中替换为:
ModelState.AddModelError("Register", error);
除了将模型组合到视图模型中以使用包含两个模型(就像您在这种情况下可能应该做的那样)之外,一个便宜且简单的选择是检测错误并将其作为 viewbag 传回 属性。然后在前端,您可以检查 属性 是否不为空,如果为空则显示一条错误消息。
不过你应该创建一个视图模型,其他一切都只是一个创可贴的解决方法。
您可以将登录和注册模型合并到一个全新的模型中,这样验证就可以针对所需的模型。
感谢大家 efforts.I 必须创建新模型并将注册和登录这两个模型包装在其中。
看起来 how to work with two forms in a single view 对我帮助很大。
但是,我正在为新手发布完整的解决方案。
客户控制器:
正在加载页面
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>
}
最后,登录页面
Login.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 -->
}
我正在开发 NopCommerce v3.80。默认情况下,登录和注册视图是不同的。我需要在不更改太多代码的情况下合并它们,所以我在 Login.cshtml.
中调用了@{ RenderAction("Register"); }
我还从注册视图中删除了布局 (Layout = "~/Views/Shared/_ColumnsOne.cshtml";
)。
问题是当像 'Email Id already Exists!' 这样的验证错误出现时,它会转到注册视图。我需要在登录视图上显示验证或错误消息。但登录视图仅接受登录模型。
请看我的代码:
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: 我也尝试了新的模型创建选项,它涵盖了登录和注册模型,但我仍然得到相同的结果。
如果没有比您已经完成的更重要的代码更改,您尝试做的事情实际上是不可行的,因为验证的范围仅限于您正在处理的特定模型。
可能是我能想到的最简单有效的解决方案,就是将登录视图的模型更改为其他两个模型的包装器。
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("", error);
在您的代码中替换为:
ModelState.AddModelError("Register", error);
除了将模型组合到视图模型中以使用包含两个模型(就像您在这种情况下可能应该做的那样)之外,一个便宜且简单的选择是检测错误并将其作为 viewbag 传回 属性。然后在前端,您可以检查 属性 是否不为空,如果为空则显示一条错误消息。
不过你应该创建一个视图模型,其他一切都只是一个创可贴的解决方法。
您可以将登录和注册模型合并到一个全新的模型中,这样验证就可以针对所需的模型。
感谢大家 efforts.I 必须创建新模型并将注册和登录这两个模型包装在其中。
看起来 how to work with two forms in a single view 对我帮助很大。
但是,我正在为新手发布完整的解决方案。
客户控制器:
正在加载页面
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>
}
最后,登录页面
Login.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 -->
}