好吧,我终于成功验证了我的模型的工作情况。我编写了一个验证处理程序和几个扩展方法。验证处理程序的第一件事是:
public class ValidationHandler<T> : HttpOperationHandler
{
private readonly HttpOperationDescription _httpOperationDescription;
public ValidationHandler(HttpOperationDescription httpOperationDescription)
{
_httpOperationDescription = httpOperationDescription;
}
protected override IEnumerable<HttpParameter> OnGetInputParameters()
{
return _httpOperationDescription.InputParameters
.Where(prm => prm.ParameterType == typeof(T));
}
protected override IEnumerable<HttpParameter> OnGetOutputParameters()
{
return _httpOperationDescription.InputParameters
.Where(prm => prm.ParameterType == typeof(T));
}
protected override object[] OnHandle(object[] input)
{
var model = input[0];
var validationResults = new List<ValidationResult>();
var context = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, context, validationResults,true);
if (validationResults.Count == 0)
{
return input;
}
else
{
var response = new HttpResponseMessage()
{
Content = new StringContent("Model Error"),
StatusCode = HttpStatusCode.BadRequest
};
throw new HttpResponseException(response);
}
}
}
请注意 Handler 如何接收 T 对象,这主要是因为我想验证 API 中的所有模型类型。因此,OnGetInputParameters 指定处理程序需要接收 T 类型对象,OnGetOutputParameters 指定处理程序需要返回一个具有相同 T 类型的对象,以防满足验证策略,如果不满足,请查看 on handler 方法如何抛出异常让客户端知道存在验证问题。
现在我需要注册处理程序,为此我编写了几个扩展方法,遵循 Pedro Felix 博客的示例http://pfelix.wordpress.com/2011/09/24/wcf-web-apicustom-parameter-conversion/ http://pfelix.wordpress.com/2011/09/24/wcf-web-apicustom-parameter-conversion/(这个博客对我帮助很大,有一些关于整个处理程序操作的很好的解释)。这些是扩展方法:
public static WebApiConfiguration ModelValidationFor<T>(this WebApiConfiguration conf)
{
conf.AddRequestHandlers((coll, ep, desc) =>
{
if (desc.InputParameters.Any(p => p.ParameterType == typeof(T)))
{
coll.Add(new ValidationHandler<T>(desc));
}
});
return conf;
}
因此此方法检查操作中是否有 T 类型参数,如果有,则将处理程序添加到该特定操作。
该方法调用另一个扩展方法 AddRequestHandler,该方法添加新的处理程序,而不删除以前注册的处理程序(如果存在)。
public static WebApiConfiguration AddRequestHandlers(
this WebApiConfiguration conf,
Action<Collection<HttpOperationHandler>,ServiceEndpoint,HttpOperationDescription> requestHandlerDelegate)
{
var old = conf.RequestHandlers;
conf.RequestHandlers = old == null ? requestHandlerDelegate :
(coll, ep, desc) =>
{
old(coll, ep, desc);
};
return conf;
}
最后一件事是注册处理程序:
var config = new WebApiConfiguration();
config.ModelValidationFor<T>(); //Instead of passing a T object pass the object you want to validate
routes.SetDefaultHttpConfiguration(config);
routes.MapServiceRoute<YourResourceObject>("SomeRoute");
这就是它..希望它对其他人有帮助!