C# 代码契约和ASP.NET MVC控制器属性

C# 代码契约和ASP.NET MVC控制器属性,c#,asp.net-mvc,code-contracts,C#,Asp.net Mvc,Code Contracts,我第一次使用CodeContracts,对此我有一个问题。当我在控制器代码中使用ModelState、User、Request或Response时,代码契约表示我应该向代码中添加一个Contract.Requires(this.Request!=null) 消息示例: 警告1 CodeContracts:外部可见文件中缺少前提条件 方法。考虑添加合同。需要(Test.MealthTeal. = NULL); 用于参数验证 我想我可以通过添加以下内容使这些消息从代码契约中消失: [Contract

我第一次使用CodeContracts,对此我有一个问题。当我在控制器代码中使用
ModelState
User
Request
Response
时,代码契约表示我应该向代码中添加一个
Contract.Requires(this.Request!=null)

消息示例:

警告1 CodeContracts:外部可见文件中缺少前提条件 方法。考虑添加合同。需要(Test.MealthTeal. = NULL); 用于参数验证

我想我可以通过添加以下内容使这些消息从代码契约中消失:

[ContractInvariantMethod]
private void ObjectInvariant()
{
    Contract.Invariant(this.HttpContext != null);
    Contract.Invariant(this.ModelState != null);
    Contract.Invariant(this.Request != null);
    Contract.Invariant(this.Response != null);
    Contract.Invariant(this.RouteData != null);
    Contract.Invariant(this.Server != null);
    Contract.Invariant(this.Session != null);
    Contract.Invariant(this.ViewData != null);
    Contract.Invariant(this.User != null);
    Contract.Invariant(this.Url != null);
}
我的代码。但是ObjectInvariant函数在运行时在Controller之前进行检查。调用Initialize,从而证明所有不变量都为false


TL;DR


现在我的问题是,如何禁用控制器基本属性的代码协定消息?

您可以尝试捕获ContractFailed事件并抑制其中的异常,以下是如何设置它:

Contract.ContractFailed += (sender, args) => 
{ 
   //additionally you can check args.FailureKind to distinguish what exactly has failed (if needed)

   args.SetHandled(); 
};
但是,不确定它是抑制错误还是阻止错误在调用堆栈中冒泡。消除警告消息的另一个选项是使用以下属性注释控制器:

[SuppressMessage("Microsoft.Contracts", "Invariant")]
//or this: [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
public ActionResult Index()
{
    Contract.Requires(Request != null);
    //...
    return View();
}
或者完全禁用验证:

[ContractVerification(false)]

至于不变量-它只会在控制器中每个公共方法和构造函数的末尾添加一个额外的调用来执行检查,但大多数都是无意义的(尤其是Contract.Invariant(this.Request!=null))

答案在于错误“外部可见方法中缺少前提条件”。你的方法是私有的。请尝试public void ObjectInvariant()

您确实不应该在MVC控制器中使用代码约定。代码契约在描述域模型(例如“业务层”)中对象上调用的方法的先决条件和后决条件时更有用,而在“应用层”中则不太有用


在应用层,它更适合执行传统的输入验证。当然,您还需要进行一些集成测试(即,测试从控制器到至少域模型层,如果不是一直到持久性存储本身的话),ContractFailed事件不会触发,因为它是由静态检查器生成的警告消息,SuppressMessage将不起作用,因为警告与不变量无关。我不想禁用验证,因为这就是我们开始使用它的原因。好的,如果你的警告不是关于不变量的,那么你可以使用它所抱怨的,而不是不变量。尽管如此,您的大多数检查在MVC controllerBtw的范围内并没有任何意义,正如使用ContractVerification属性禁用一样——您也可以在类或方法级别禁用检查,而不仅仅是在程序集级别。这不是你要求的吗?是的,但大部分逻辑都会在控制器内部完成,所以我确实希望检查控制器,我只是不希望它涉及控制器的基本属性。根据我在问题中的示例,你如何抑制警告?