代码约定和ASP.NET MVC控制器属性

时间:2014-07-10 15:07:03

标签: c# asp.net-mvc code-contracts

我第一次使用CodeContracts,我有一个问题。当我在控制器代码中使用ModelStateUserRequestResponse时,代码合同就是说我应该在代码中添加Contract.Requires(this.Request != null)。< / p>

消息示例:

  

警告1 CodeContracts:外部可见的缺少前提条件   方法。考虑添加Contract.Requires(this.ModelState!= 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);
}

到我的代码。但是在调用Controller.Initialize之前会在运行时检查ObjectInvariant函数,从而证明所有不变量都为false。


TL; DR

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

3 个答案:

答案 0 :(得分:0)

您真的不应该在MVC控制器中使用代码约定。代码约定在描述域模型中对象上调用的方法(例如“业务层”)的前提条件和后置条件时更有用,而在“应用程序层”中则没有那么多。

在应用程序层,它更适合执行传统的输入验证。当然,您还需要进行一些集成测试(即,从Controller到系统模型层运行系统的测试,如果不是一直到持久性存储本身的话)。

答案 1 :(得分:-1)

您可以尝试捕获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))

答案 2 :(得分:-1)

答案在于错误&#34;在外部可见的方法中缺少前提条件&#34;。你的方法是私人的。尝试使用public void ObjectInvariant()