C# MVC:两个表单标记和一个ViewModel
我的MVC应用程序只有一个页面。在此页面上,用户可以输入用户名和密码并单击登录按钮,或者用户可以输入其名字、电子邮件地址并单击注册按钮 我最初的想法是创建一个带有C# MVC:两个表单标记和一个ViewModel,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,我的MVC应用程序只有一个页面。在此页面上,用户可以输入用户名和密码并单击登录按钮,或者用户可以输入其名字、电子邮件地址并单击注册按钮 我最初的想法是创建一个带有UserName、Password、FirstName和Email属性的视图模型,所有这些属性都带有[必需]属性。然后有一个包含两个Html.BeginForm()的视图。虽然这可能会起作用,但我感觉当我将数据发回控制器时,ModelState.IsValid将始终返回false,因为ViewModel确实是无效的 那么,有人能告诉我处
UserName
、Password
、FirstName
和Email
属性的视图模型,所有这些属性都带有[必需]
属性。然后有一个包含两个Html.BeginForm()
的视图。虽然这可能会起作用,但我感觉当我将数据发回控制器时,ModelState.IsValid
将始终返回false
,因为ViewModel确实是无效的
那么,有人能告诉我处理这种情况的正确方法吗?我认为正确的方法是为每种情况设置一个ViewModel。如果需要,与数据库对话的底层业务逻辑和/或代码仍然可以使用单个模型 你的选择讨论得很好
尽管我想补充一点,在MVC页面上有多个ViewModel是一种痛苦 我认为正确的方法是为每个视图都设置一个ViewModel。如果需要,与数据库对话的底层业务逻辑和/或代码仍然可以使用单个模型 你的选择讨论得很好
尽管我想补充一点,在MVC页面上有多个ViewModel是一种痛苦 您可以定义两个视图模型 登录视图模型:
public class LoginViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
}
public class RegisterViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
[Requried]
public string FirstName{ get; set; }
[Requried]
public string Email { get; set; }
}
注册视图模型:
public class LoginViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
}
public class RegisterViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
[Requried]
public string FirstName{ get; set; }
[Requried]
public string Email { get; set; }
}
登录视图:
@Html.BeginForm("Login", "Account", FormMethod.Post)
{
<!-- login form implements... -->
}
或者,如果您只需要一个模型。尝试删除[必需]
属性。你可以在动作中检查它。像这样:
public IActionResult Login(YourViewModel model)
{
if (!string.IsNullOrEmpty(model.UserName) && !string.IsNullOrEmpty(model.Password))
{
}
}
public IActionResult Register(YourViewModel model)
{
if (!string.IsNullOrEmpty(model.UserName) &&
!string.IsNullOrEmpty(model.Password) &&
!string.IsNullOrEmpty(model.FirstName) &&
!string.IsNullOrEmpty(model.Email))
{
}
}
希望这有帮助 您可以定义两个视图模型 登录视图模型:
public class LoginViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
}
public class RegisterViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
[Requried]
public string FirstName{ get; set; }
[Requried]
public string Email { get; set; }
}
注册视图模型:
public class LoginViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
}
public class RegisterViewModel
{
[Requried]
public string UserName { get; set; }
[Requried]
public string Password { get; set; }
[Requried]
public string FirstName{ get; set; }
[Requried]
public string Email { get; set; }
}
登录视图:
@Html.BeginForm("Login", "Account", FormMethod.Post)
{
<!-- login form implements... -->
}
或者,如果您只需要一个模型。尝试删除[必需]
属性。你可以在动作中检查它。像这样:
public IActionResult Login(YourViewModel model)
{
if (!string.IsNullOrEmpty(model.UserName) && !string.IsNullOrEmpty(model.Password))
{
}
}
public IActionResult Register(YourViewModel model)
{
if (!string.IsNullOrEmpty(model.UserName) &&
!string.IsNullOrEmpty(model.Password) &&
!string.IsNullOrEmpty(model.FirstName) &&
!string.IsNullOrEmpty(model.Email))
{
}
}
希望这有帮助 我在我的项目中实现了非常类似的场景,我认为实现这一点的最佳方法是创建一个viewmodel,其中包含两个子viewmodel,如下所示:
public class AuthModelView
{
public MemberLoginViewModel LoginModel { get; set; }
public MemberRegisterViewModel RegisterModel { get; set; }
[HiddenInput]
public string ReturnUrl { get; set; }
}
MemberLoginView模型:
public class MemberLoginViewModel
{
[Required(ErrorMessage = "")]
[Display(Name = "")]
[EmailAddress]
public string Email { get; set; }
[DataType(DataType.Password)]
[Display(Name = "")]
[Required(ErrorMessage = "")]
public string Password { get; set; }
[Display(Name = "")]
public bool RememberMe { get; set; }
}
public class MemberRegisterViewModel
{
[Required(ErrorMessage = "")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required(ErrorMessage = "")]
[DataType(DataType.Password)]
[Display(Name = "")]
public string Password { get; set; }
[Required]
public string RepeatPassword { get; set; }
[HiddenInput(DisplayValue = false)]
public string ReturnUrl { get; set; }
}
MemberRegisterViewModel:
public class MemberLoginViewModel
{
[Required(ErrorMessage = "")]
[Display(Name = "")]
[EmailAddress]
public string Email { get; set; }
[DataType(DataType.Password)]
[Display(Name = "")]
[Required(ErrorMessage = "")]
public string Password { get; set; }
[Display(Name = "")]
public bool RememberMe { get; set; }
}
public class MemberRegisterViewModel
{
[Required(ErrorMessage = "")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required(ErrorMessage = "")]
[DataType(DataType.Password)]
[Display(Name = "")]
public string Password { get; set; }
[Required]
public string RepeatPassword { get; set; }
[HiddenInput(DisplayValue = false)]
public string ReturnUrl { get; set; }
}
然后创建将渲染2个局部视图的视图
@Html.Partial("MemberLoginSummary", Model)
@Html.Partial("MemberRegisterSummary", Model)
如果“模型”是您的父视图模型,那么您将有两个单独的表单
在一种观点中。在你的局部观点中,你只需做如下事情:
@Html.TextBoxFor(m => m.LoginModel.Email, null, new { @class = "form-control", placeholder = "email", id="Email" })
我在我的项目中实现了非常类似的场景,我认为实现这一点的最佳方法是创建一个viewmodel,其中包含两个子viewmodel,如下所示:
public class AuthModelView
{
public MemberLoginViewModel LoginModel { get; set; }
public MemberRegisterViewModel RegisterModel { get; set; }
[HiddenInput]
public string ReturnUrl { get; set; }
}
MemberLoginView模型:
public class MemberLoginViewModel
{
[Required(ErrorMessage = "")]
[Display(Name = "")]
[EmailAddress]
public string Email { get; set; }
[DataType(DataType.Password)]
[Display(Name = "")]
[Required(ErrorMessage = "")]
public string Password { get; set; }
[Display(Name = "")]
public bool RememberMe { get; set; }
}
public class MemberRegisterViewModel
{
[Required(ErrorMessage = "")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required(ErrorMessage = "")]
[DataType(DataType.Password)]
[Display(Name = "")]
public string Password { get; set; }
[Required]
public string RepeatPassword { get; set; }
[HiddenInput(DisplayValue = false)]
public string ReturnUrl { get; set; }
}
MemberRegisterViewModel:
public class MemberLoginViewModel
{
[Required(ErrorMessage = "")]
[Display(Name = "")]
[EmailAddress]
public string Email { get; set; }
[DataType(DataType.Password)]
[Display(Name = "")]
[Required(ErrorMessage = "")]
public string Password { get; set; }
[Display(Name = "")]
public bool RememberMe { get; set; }
}
public class MemberRegisterViewModel
{
[Required(ErrorMessage = "")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required(ErrorMessage = "")]
[DataType(DataType.Password)]
[Display(Name = "")]
public string Password { get; set; }
[Required]
public string RepeatPassword { get; set; }
[HiddenInput(DisplayValue = false)]
public string ReturnUrl { get; set; }
}
然后创建将渲染2个局部视图的视图
@Html.Partial("MemberLoginSummary", Model)
@Html.Partial("MemberRegisterSummary", Model)
如果“模型”是您的父视图模型,那么您将有两个单独的表单
在一种观点中。在你的局部观点中,你只需做如下事情:
@Html.TextBoxFor(m => m.LoginModel.Email, null, new { @class = "form-control", placeholder = "email", id="Email" })
如果你想尝试不同的图书馆,那么你可以选择 FluentValidation提供了一种优雅的方式,可以为不同方法的单个类定制验证 例如
[验证器(typeof(LoginRegisterModelValidator))]
公共类LoginRegisterViewModel
{
公共字符串用户名{get;set;}
公共字符串密码{get;set;}
公共字符串名{get;set;}
公共字符串电子邮件{get;set;}
}
可以为不同的操作定义多个规则
验证器类如下所示
public类LoginRegisterModelValidator:AbstractValidator
{
公共注册表AddeditModelValidator()
{
/*定义规则集,以便在具有CustomizeEvalidator属性的contrller操作参数内专门调用它们*/
规则集(“登录规则集”,登录规则集);
规则集(“RegisterRuleSet”,RegisterRuleSet);
}
受保护的无效登录规则集()
{
RuleFor(x=>x.UserName).NotEmpty();
RuleFor(x=>x.Password).NotEmpty();
}
受保护的无效注册表规则集()
{
RuleFor(x=>x.Email).NotEmpty();
RuleFor(x=>x.FirstName).NotEmpty();
}
}
控制器操作如下所示
[HttpPost]
[ValidateAntiForgeryToken]
公共操作结果登录([CustomizeValidator(RuleSet=“LoginRuleSet”)]LoginRegisterViewModel模型)
{ ...
}
[HttpPost]
[ValidateAntiForgeryToken]
公共操作结果寄存器([CustomizeValidator(RuleSet=“RegisterRuleSet”)]LoginRegisterViewModel模型)
{ ...
}
}
希望这有助于您在同一类中验证不同的规则。如果您想尝试不同的库,则可以使用 FluentValidation提供了一种优雅的方式,可以为不同方法的单个类定制验证 例如
[验证器(typeof(LoginRegisterModelValidator))]
公共类LoginRegisterViewModel
{
公共字符串用户名{get;set;}
公共字符串密码{get;set;}
公共字符串名{get;set;}
公共字符串电子邮件{get;set;}
}
可以为不同的操作定义多个规则
验证器类如下所示
public类LoginRegisterModelValidator:AbstractValidator
{
公共注册表AddeditModelValidator()
{
/*定义规则集,以便在具有CustomizeEvalidator属性的contrller操作参数内专门调用它们*/
规则集(“登录规则集”,登录规则集);
规则集(“RegisterRuleSet”,RegisterRuleSet);
}
受保护的无效登录规则集()
{
RuleFor(x=>x.UserName).NotEmpty();
RuleFor(x=>x.Password).NotEmpty();
}
受保护的无效注册表规则集()
{
RuleFor(x=>x.Email).NotEmpty();
RuleFor(x=>x.FirstName).NotEmpty();
}
}
控制器操作如下所示
[HttpPost]
[ValidateAntiForgeryToken