mvc模型和viewmodel?
所以, 我有一个“用户”模型,它有很多字段,但以下是重要的字段:
public int Id {get;set;}
public string Username { get; set; }
public string Pwd { get; set; }
我有一个视图模型,用于验证我在不同控制器上使用的密码:
public class ConfirmPassword : IValidatableObject
{
[Required]
public string Password { get; set; }
[Required(ErrorMessage="Confirm Password field is required.")]
public string ConfirmPwd { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
string regex1 = @"^.{8,10}$"; // 8 - 10 characters
Match requirement1 = Regex.Match(Password, regex1);
if (Password != ConfirmPwd)
yield return new ValidationResult("Password and Confirm Password is not identical.");
if (!requirement1.Success)
yield return new ValidationResult("Password must be between 8 and 10 characters.");
}
}
有没有一种方法可以将视图模型连接到我的模型实体?或者只是复制粘贴代码我唯一的选择?我无法进行复制粘贴,因为代码需要有一个 IValidateObject,这会弄乱整个用户实体,因为发生了大量的后台审核。我只需要在编辑/创建配置文件时验证密码。
编辑: 如果大家都感到困惑的话,我很抱歉。基本上,我需要对无法由数据注释处理的确认密码进行多次验证,因此使用确认密码视图模型。我想将此验证应用于用户模型,但不添加“ConfirmPassword”字段。因为我不需要数据库中的另一个字段。我的问题是,每当视图 POST 和密码字段不满足其要求时,如何强制触发确认密码的验证?
namespace
{
public class User
{
public int Id {get;set;}
public string Username { get; set; }
public string Pwd { get; set; }
}
}
namespace
{
public class ConfirmPassword : IValidatableObject
{
[Required]
public string Password { get; set; }
[Required(ErrorMessage="Confirm Password field is required.")]
public string ConfirmPwd { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
string regex1 = @"^.{8,10}$"; // 8 - 10 characters
string regex2 = @"(?:.*?[A-Z]){1}"; // 1 uppercase
string regex3 = ""; // 1 lowercase
string regex4 = ""; // 1 numeric
Match requirement1 = Regex.Match(Password, regex1);
Match requirement2 = Regex.Match(Password, regex2);
Match requirement3 = Regex.Match(Password, regex3);
Match requirement4 = Regex.Match(Password, regex4);
if (Password != ConfirmPwd)
yield return new ValidationResult("Password and Confirm Password is not identical.");
if (!requirement1.Success)
yield return new ValidationResult("Password must be between 8 and 10 characters.");
if (!requirement2.Success)
yield return new ValidationResult("Password must contain at least 1 uppercase letter.");
if (!requirement3.Success)
yield return new ValidationResult("Password must contain at least 1 lowercase letter.");
if (!requirement4.Success)
yield return new ValidationResult("Password must contain at least 1 numeric character.");
}
}
}
so,
i have a "User" model that has a lot of fields but following are the impt ones:
public int Id {get;set;}
public string Username { get; set; }
public string Pwd { get; set; }
and i have a view model that validates the password that i use on a different controller:
public class ConfirmPassword : IValidatableObject
{
[Required]
public string Password { get; set; }
[Required(ErrorMessage="Confirm Password field is required.")]
public string ConfirmPwd { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
string regex1 = @"^.{8,10}$"; // 8 - 10 characters
Match requirement1 = Regex.Match(Password, regex1);
if (Password != ConfirmPwd)
yield return new ValidationResult("Password and Confirm Password is not identical.");
if (!requirement1.Success)
yield return new ValidationResult("Password must be between 8 and 10 characters.");
}
}
is there a way where i can connect the view model to my model entity? or just copy paste the codes my only option? I can't do copy paste since the code needs to have a IValidateObject which will mess up the whole User entity as there's a ton of background auditing happeneing.. I just need to validate the passwords whenever a profile is edited / created.
EDIT:
so sorry if everybody got confused. basically, i have multiple validations that i need on the confirm passwords that can't be handled by dataannotations, ergo the confirmpassword viewmodel. this validation i want to be applied onto the User model but without adding the "ConfirmPassword" field into it. as i dont need another field on the database. My question is how do i force the validations i have from the confirmapassword to trigger whenever the view POSTs and the password field does not meet its requirements?
namespace
{
public class User
{
public int Id {get;set;}
public string Username { get; set; }
public string Pwd { get; set; }
}
}
namespace
{
public class ConfirmPassword : IValidatableObject
{
[Required]
public string Password { get; set; }
[Required(ErrorMessage="Confirm Password field is required.")]
public string ConfirmPwd { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
string regex1 = @"^.{8,10}$"; // 8 - 10 characters
string regex2 = @"(?:.*?[A-Z]){1}"; // 1 uppercase
string regex3 = ""; // 1 lowercase
string regex4 = ""; // 1 numeric
Match requirement1 = Regex.Match(Password, regex1);
Match requirement2 = Regex.Match(Password, regex2);
Match requirement3 = Regex.Match(Password, regex3);
Match requirement4 = Regex.Match(Password, regex4);
if (Password != ConfirmPwd)
yield return new ValidationResult("Password and Confirm Password is not identical.");
if (!requirement1.Success)
yield return new ValidationResult("Password must be between 8 and 10 characters.");
if (!requirement2.Success)
yield return new ValidationResult("Password must contain at least 1 uppercase letter.");
if (!requirement3.Success)
yield return new ValidationResult("Password must contain at least 1 lowercase letter.");
if (!requirement4.Success)
yield return new ValidationResult("Password must contain at least 1 numeric character.");
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以在视图模型中使用装饰器模式来做您喜欢的事情。您还可以使用 System.ComponentModel.DataAnnotations 命名空间属性来为您完成所有验证。
You can use the decorator patter in your view model to do what you like. You can also use the
System.ComponentModel.DataAnnotations
namespace attributes to do all your validation for you.好吧,我仍然对将视图模型连接到模型实体的含义有点不确定......我认为您现在想要的是检查实际用户的密码是否与传递到视图模型的密码匹配。
我个人不会在视图模型本身中执行此操作,而是在控制器中执行此操作,并且如果密码不正确,则会添加 ModelState.AddError 。
如果您使用客户端验证,则正常的输入验证可以在服务器或客户端上进行,但您无法检查客户端的密码,因此必须转到服务器。
Ok, I am still a little iffy on what you mean by connect view model to model entity... I think what you want is to now check if the password from the actual user matches the password passed in to the view model.
I personally would not do this in the view model itself, but rather in the controller and would add a ModelState.AddError if the password was incorrect.
The normal input validation can happen on the server or client side if you are using client side validation, but you can't check the password client side, so it will have to go to the server.
我会在您的 ViewModel 中包含一个 userId 或将其添加到 URL 上,以便控制器可以拾取它。
验证密码组合后,您可以使用 ID 检索相关用户并使用新密码更新它。您可以在新密码发布操作中执行此操作。
顺便说一句,您可能想与旧密码匹配。
I would include a userId in your ViewModel or add it on the URL so the controller can pick it up.
After validating the password combo you use the Id to retrieve the relevant User and update it with the new password. You can just do this within your new password post action.
You may want to match with the old password btw.
我认为,您的 UI 验证和逻辑验证不应该混淆。即使是同一件事,也值得在逻辑中重新做一遍。基本上,实体对象不负责进行验证。它可能是为实体执行此操作的某个服务层类。此时您可能会抛出异常。因此 UI 和逻辑中的处理方式完全不同。
From what I believe, your UI validations and Logic validations should not be mixed up. It is worth doing in over again in the Logic even if it is the same thing. Basically, it is not the responsibility of the Entity object to carry the validations. It might be some service layer class that does it for the Entity. And you can probably throw an exception at that point.So it is handled in completely different ways in the UI and the Logic.
“我只需要在编辑/创建配置文件时验证密码”
将数据注释与 ViewModel 上的 IsValid 结合使用来检查失败。至于将模型映射到视图模型,只需使用装饰器模式。
使用 System.ComponentModel.DataAnnotations (它们甚至有一个可以使用的正则表达式验证器)
根据策略验证密码后,将其转换为 MD5 哈希值并存储,而不是密码值
如果所有其他方法都失败,那么创建单独的 UserValidation 类并在视图模型和模型之间共享逻辑并没有什么问题,例如它们都调用相同的方法来确定有效性(减少代码)。
"I just need to validate the passwords whenever a profile is edited / created"
Use data annotations combined with IsValid on the ViewModel to check for failures. As far as mapping a Model to a View Model just use a decorator pattern.
Use System.ComponentModel.DataAnnotations (they even have a regular expression validator you can use)
Once passwords are verified against a policy, convert them to an MD5 hash and store that, not the password value
If all else fails there is nothing wrong with creating a separate UserValidation Class and share logic between the View Model and Model e.g. they both call the same methods to determine validity (reducing code).