【问题标题】:WebApi action parameters validation by ValidationAttribute通过 ValidationAttribute 验证 WebApi 操作参数
【发布时间】:2012-08-05 13:31:46
【问题描述】:
WebAPI 可以处理动作参数上的 ValidationAttribute 吗?
例如:
public class SampleController : ApiController
{
public string Get([RegularExpression("sampleExpression")]string id)
{
return "result";
}
}
在此示例中,WebAPI 不会调用 RegularExpressionAttribute(或任何其他数据注释属性)的任何方法来验证输入参数。但是如果我们传递一个对象作为参数,例如一个类,那么 WebAPI 可以验证属性。
这是一个错误吗?还是我做错了什么?
UPD:这是一个未解决的问题:
http://aspnetwebstack.codeplex.com/workitem/24?PendingVoteId=24
有人可以提出解决方法吗?
【问题讨论】:
标签:
validation
data-annotations
asp.net-web-api
【解决方案1】:
这是一个真正的问题,我很好奇为什么不做类似的事情:
public class SampleController : ApiController
{
public string Get(string id)
{
RegularExpressionHelper.ValidateWith("sampleExpression",id);
return "result";
}
}
对我来说,这似乎相当简洁。验证发生时很明显。我可以放心地假设,如果验证失败,则会引发异常。我可以轻松地添加额外的验证,并对它们发生的顺序充满信心。
关于属性方法,我不知道验证是否作为路由匹配的一部分,我不知道如果它失败了会发生什么。我不知道在验证之前或之后运行哪些过滤器。我敢肯定,如果我更了解 MVC,我会知道这些问题的答案,但我看不到使用使我的代码行为依赖于某些框架控制的基础设施的属性的优势。
我是否错过了一些重要的好处?
【解决方案2】:
我也有同样的疑问。我的解决方法是创建一个仅用于封装参数的类,因此我可以使用我想要的验证属性来装饰它。我可以使用 Darrel 在他的回答中提出的解决方法,但我有一个过滤器可以检查 ModelState.IsValid before 是否进入操作,因此我需要在操作执行之前进行验证。
[ModelBinder]
public class Item
{
[RegularExpression("sampleExpression")]
public string Id { get; set; }
}
类必须用[ModelBinder]注解,否则参数绑定机制会尝试从请求体中提取id字段。阅读this article了解更多信息。
另外,请注意Id 现在使用 PascalCase 而不是 camelCase。阅读this article 了解如何进行转换。
动作签名是:
public string Get(Item item)