C# 能否使用模型实例控制器中的属性验证模型实例?

C# 能否使用模型实例控制器中的属性验证模型实例?,c#,asp.net-mvc,validation,C#,Asp.net Mvc,Validation,假设我有一个控制器,作为演示,它看起来像这样: public class ProjectController : Controller { private IProjectRepository projectRepository; public ProjectController() { DBContext context = new DBContext(); this.projectRepository = new ProjectRep

假设我有一个控制器,作为演示,它看起来像这样:

public class ProjectController : Controller
{
    private IProjectRepository projectRepository;

    public ProjectController()
    {
        DBContext context = new DBContext();
        this.projectRepository = new ProjectRepository(context);
    }

    public ActionResult Create(Project project)
    {
        if (ModelState.IsValid)
        {
            // do whatever
        }
        else
        {
            return View(project);
        }
    }
}
假设这是一个模型的控制器,看起来像这样:

public class Project : IValidatableObject
{
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // this is where I would like to add code
    }
}
公共类项目:IValidatableObject
{
公共IEnumerable验证(ValidationContext ValidationContext)
{
//这是我想添加代码的地方
}
}
我的问题是:验证代码中真的没有办法引用控制器上的projectRepository对象吗?是的,我可以在技术上向控制器上的Create()函数添加准验证,在那里进行检查,并直接添加错误-但在实际情况中,有许多操作都将执行相同的验证,这实际上与您尝试创建的模型(或编辑、复制或其他任何操作)有关。但它与模型和同一模型的其他现有实例相关联,只有控制器知道如何查询这些实例。有没有办法绕过这个问题

(目标是检查当前正在验证的模型对象是否与已经存在的模型对象不同;我也愿意接受其他关于如何实现这一点的建议,只是看起来它显然应该是标准验证代码的工作,无论是使用IValidatableObject还是使用ValidationAttribute。但我不是.net MVC vali方面的专家或者,就这一点而言,.NETMVC。)


谢谢!

IValidatableObject
属于
DataAnnotations
名称空间。在我看来,数据注释非常适合输入验证。当您开始应用复杂的业务规则时,它们开始失效,而您的域模型的有效性取决于其他域模型的状态

当这种情况发生时,引入一个服务层。将您的所有业务规则放在其中,并允许服务在您的模型之间调解对话。最终,服务应该是您与模型通信的接口

这就是我经常对自己说的,“嘿,你的应用程序现在已经达到了‘中等复杂度’阶段”!:)


此处可以找到一个较旧但仍然相关的教程:

IValidatableObject
属于
DataAnnotations
名称空间。在我看来,数据注释对于输入验证非常有用。当您开始应用复杂的业务规则时,它们开始下降,而您的域模型的有效性取决于其他域模型的状态

当这种情况发生时,引入一个服务层。将您的所有业务规则都放在其中,并允许服务在您的模型之间调解对话。最终,服务应该是您与模型通信的接口

这就是我经常对自己说的,“嘿,你的应用程序现在已经达到了‘中等复杂度’阶段”!:)


在这里可以找到一个更老但仍然相关的教程:

在我看来,有一点惯例问题在起作用。控制器返回给客户端的模型是ViewModel,而不是实体。这在考虑哪些对象具有依赖对象的知识时起作用

存储库处理模型(实体),控制器处理ViewModels。ViewModel实际上只是一组数据和格式,因此设置级别验证在ViewModel上没有意义

并且真正希望业务层或存储库执行集级验证,而不是模型本身。您可以在创建模型时在模型上设置对存储库的引用,并让模型调用存储库进行设置级别的验证。但是,当您想要克隆或反序列化实体时,这就成了问题

顺便说一下,EntityFramework通过允许您附加一个断开连接的实体来解决这些问题。您可能希望使用EF而不是存储库模式


但对于您当前的问题,我不会尝试从实体或viewmodel中执行设置级别的验证

IMO,有一点公约问题在起作用。控制器返回给客户端的模型是ViewModel,而不是实体。这在考虑哪些对象具有依赖对象的知识时起作用

存储库处理模型(实体),控制器处理ViewModels。ViewModel实际上只是一组数据和格式,因此设置级别验证在ViewModel上没有意义

并且真正希望业务层或存储库执行集级验证,而不是模型本身。您可以在创建模型时在模型上设置对存储库的引用,并让模型调用存储库进行设置级别的验证。但是,当您想要克隆或反序列化实体时,这就成了问题

顺便说一下,EntityFramework通过允许您附加一个断开连接的实体来解决这些问题。您可能希望使用EF而不是存储库模式


但对于您当前的问题,我不会尝试从实体或viewmodel中执行设置级别的验证

你最好把你的


在线脚手架工具以这种方式生成其模型验证代码,这对于自学来说是一个很好的参考。

您最好


在线脚手架工具以这种方式生成其模型验证代码,这对于自学来说是一个很好的参考。

好的,起初听起来像是你在要求我进行更疯狂的间接寻址,但后来我点击了该链接,这实际上看起来非常简单和优雅。谢谢(虽然我会指出,你可能应该把这个链接的相关信息,作为你的答案本身的实际执行,因为这个答案将不再对任何人有用,如果这个链接遭受链接腐烂。)好的,一开始听起来像是你在问我一个更疯狂的间接层次,b