C# 识别代码。这是一种变通方法,但在我看来,它比其他建议的解决方案要好

C# 识别代码。这是一种变通方法,但在我看来,它比其他建议的解决方案要好,c#,.net,asp.net-mvc,architecture,C#,.net,Asp.net Mvc,Architecture,您拥有具有所有验证的用户模型: public class UserModel { [Required] public int Id { get; set; } [Required] public string Name { get; set; } public string Email { get; set; } public string Password { get; set; } } 您可以使用新模型组合以前的模型 publ

您拥有具有所有验证的用户模型:

public class UserModel
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }        
}
您可以使用新模型组合以前的模型

public class EditUserModel
{
    public UserModel User { get; set; }

    [Required]
    public string PasswordConfirmation { get; set; }
}
诀窍在于,在行动中,您可能会收到多个模型:

[HtttPost]
public ActionResult UpdateInformation(UserModel user, EditUserModel editUserModel) {
    if (ModelState.IsValid) {
         // copy the inner model to the outer model, workaround here:
         editUserModel.User = user
         // do whatever you want with editUserModel, it has all the needed information
    }
}
通过这种方式,验证工作正如预期的那样


希望这能有所帮助。

我知道如何以明文形式存储密码,但这并不是关键,因为我的第一句话仍然有效;-)组合比继承(特别是C#中的单一继承)更具灵活性。它也是我首选的解决方案,我可以用客户端验证来交换它您不必交易客户端验证。例如,我建议的视图模型上的两个属性将用于客户端验证。您可能希望使用AutoMapper在业务对象和视图模型之间轻松复制数据;拥有一组专门用于视图和客户端验证的“ViewModel”类。这使我的模型与任何UI关注点完全分离。我当然不能接受模型上存在的“ConfirmPassword”属性。这还有一个额外的好处,即它允许您向模型中添加属性,而不必担心它们会被无意中更新,因为ViewModel不包含这些属性,除非您显式添加它们。换句话说,只有ViewModel中的那些项可以更新到模型。是的,每个视图一个视图模型(在大多数情况下),并且自动映射以避免来回传递内容,其他方法的问题是,您最终会混合关注点,并且视图中并不总是需要数据(然后您必须排除字段等),或者视图中需要多个对象,一个视图模型可以将所有这些都展平,并且有责任感,再加上数据注释。阅读本文,我并不是100%地理解它,但非常接近,是的,这是我现在提到的另一篇文章。不过,我并不是100%快乐。尤其是“编辑”和“创建视图模型”之间的重叠令人讨厌。这是重复,我不能轻易反驳。另外,不要把重复和违反DRY混淆。仅仅因为您在两个实体上具有相同名称的属性并不意味着您在重复自己。从语法上讲,是的,但从概念上讲,viewmodel和实体是完全不同的——特别是当您超越了简单的CRUD应用程序时。在这种情况下,如何与属性进行比较?e、 g.在您的情况下,是否按照OP的要求将密码和密码确认与数据注释进行比较?
public class EditUserModel : User
{
    [Compare("Password", ErrorMessage = "Passwords don't match.")]
    public string PasswordConfirmation  { get; set; }
}
public class EditUserModel {    
  public string Name { get; set; }    
  public string Email { get; set; }    
  public string Password { get; set; }   
  [Compare("Password", ErrorMessage = "Passwords don't match.")]     
  public string ConfirmPassword { get; set; }        
}
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }     

    [DoNotPersist]   
    public string ConfirmPassword {get; set;}

}
public class EditUserModel {    
  public string Name { get; set; }    
  public string Email { get; set; }    
  public string Password { get; set; }        
  public string ConfirmPassword { get; set; }        
}
public class UserModel
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }        
}
public class EditUserModel
{
    public UserModel User { get; set; }

    [Required]
    public string PasswordConfirmation { get; set; }
}
[HtttPost]
public ActionResult UpdateInformation(UserModel user, EditUserModel editUserModel) {
    if (ModelState.IsValid) {
         // copy the inner model to the outer model, workaround here:
         editUserModel.User = user
         // do whatever you want with editUserModel, it has all the needed information
    }
}