验证模型属性WCFWebAPI我有一组托管WCFWebApi的服务,我需要做的是验证应用程序模型中的属性。例如,在MVC3中,我这样装饰模型中的属性:[StringLength(30)]publicstringUserName{get;放;然后在控制器中,我继续验证模型是否满足验证参数,如下所示:[HttpPost]ActionResultCreate(ModelmyModel){if(ModelState.IsValid(){发布模型}else{不要发布模型}有没有办法在WCFWebApi中做类似的事情?首先,我应该说非常棒的问题+答案丹尼尔然而,我已经采取了一些进一步的改进并添加了ValidationHander我改进了一点。它现在基于通用的HttpOperationHandler所以可以使用HttpRequestMessage。这样做的原因是我可以返回使用使用正确媒体类型(来自接受标头)格式化的错误消息。publicclassValidationHandler:HttpOperationHandler{publicValidationHandler():base("response"){}protectedoverrideHttpRequestMessageOnHandle(TResourcemodel,HttpRequestMessagerequestMessage){varresults=newList();varnull,text,modelContext();Validator.TryValidateObject(模型、上下文、结果、真);if(results.Count==0){returnrequestMessage;}varerrorMessages=results.Select(x=>x.ErrorMessage).ToArray();varmediaType=requestMessage.Headers.Accept.FirstOrDefault();varresponse=newRestValidationFailure(errorMessages);if(mediaType!=null){response.Content=newObjectContent(typeof(string[]),errorMessages,mediaType);}抛出新的HttpResponseException(响应);}}扩展方法在ModelValidationFor方法中添加ValidationHandler时,您提供的2和desc参数几乎保持不变我添加了一个额外的扩展方法。这是为了确保所有“资源”类都经过验证。这主要是我懒惰和健忘。我永远忘记在某处的列表中添加一些类。(这就是我编写通用温莎安装程序的原因!))).绝对路径);vardc=newDirectoryCatalog(path,assemblyFilter);varassemblies=dc.LoadedFiles.Select(Assembly.LoadFrom).ToList();assemblies.ForEach(assembly=>{varresourceTypes=assembly.GetTypes().Where(t=>t.Namespace!=null&&t.Namespace.EndsWith("Resources"));foreach(varresourceTypeinresourceTypes){varconfigType=typeof(Extensions);varmi=configType.GetMethod("ModelValidationFor");varmi2=mi.MakeGenericMethod(resourceType);mi2.Invoke(null,newobject[]{config});}});我使用了DirectoryCatalog类(以前称为MEF)的System.ComponentModel.Composition.Hosting命名空间。在本例中,我只是使用以“Resources”结尾的命名空间来查找我的“Resource”类。将其更改为使用自定义属性或您可能更喜欢的任何其他内容来确定哪些类是您的“资源”并不需要太多工作。RestValidationFailure这是我创建的一个小助手类,用于允许验证失败响应的一致行为。公共类RestValidationFailure:HttpResponseMessage{publicRestValidationFailure(string[]messages){StatusCode=HttpStatusCode.BadRequest;foreach(varerrorMessageinmessages){Headers.Add("X-Validation-Error",errorMessage);所以现在我得到了所有验证错误的一个很好的列表(在我首选的媒体类型中)。请享用!?好的,我终于设法验证了我的模型是否正常工作。我写了一个验证处理程序和几个扩展方法。验证处理程序的第一件事:publicclassValidationHandler:HttpOperationHandler{privatereadonlyHttpOperationDescription_httpOperationDescription;publicValidationHandler(HttpOperationDescriptionhttpOperationDescription){_httpOperationDescription=httpOperationDescription;}protectedoverrideIEnumerableOnGetInputParameters(){return_httpOperationDescription.InputParameters.Where(prm=>prm.ParameterType==typeof(T));}protectedoverrideIEnumerableOnGetOutputParameters(){return_httpOperationDescription.InputParameters.Where(prm=>prm.ParameterType==typeof(T));}protectedoverrideobject[]OnHandle(object[]input){varmodel=input[0];varvalidationResults=newList();varcontext=newValidationContext(model,null,null);Validator.TryValidateObject(模型、上下文、validationResults、true);if(validationResults.Count==0){返回输入;}else{varresponse=newHttpResponseMessage(){Content=newStringContent(“模型错误”),StatusCode=HttpStatusCode.BadRequest};抛出新的HttpResponseException(响应);注意Handler是如何接收T对象的,这主要是因为我要验证API中所有模型类型所以OnGetInputParameters指定handler需要接收T类型对象,OnGetOutputParameters指定handler需要返回一个如果满足验证策略,则返回相同类型T的对象,否则,请查看onhandle方法如何抛出异常,让客户端知道存在验证问题。现在我需要注册处理程序,为此我编写了几个扩展方法,以PedroFelix的博客http://pfelix.wordpress.com/2011/09/24/wcf-web-apicustom-parameter-conversion/中的示例为例(这博客通过对整个处理程序操作的一些很好的解释帮助了我很多)。所以这些是扩展方法:))){coll.Add(newValidationHandler(desc));}});返回配置文件;因此,此方法检查操作中是否存在T类型的参数,如果存在,则将处理程序添加到该特定操作。此调用另一个扩展方法AddRequestHandler,此方法添加新的处理程序而不删除以前注册的处理程序(如果存在)。publicstaticWebApiConfigurationAddRequestHandlers(这个WebApiConfigurationconf,Action,ServiceEndpoint,HttpOperationDescription>requestHandlerDelegate){varold=conf.RequestHandlers;conf.RequestHandlers=old==null?requestHandlerDelegate:(coll,>ep,desc(coll)ep,desc);};返回配置文件;最后一件事是注册处理程序:varconfig=newWebApiConfiguration();配置.ModelValidationFor();//不是传递T对象,而是传递要验证路由的对象.SetDefaultHttpConfiguration(config);routes.MapServiceRoute("SomeRoute");就是这样..希望它能帮助别人!我目前正在开发一个完全符合您要求的HttpOperationHandler。现在还没有完成,但是这个伪代码可能会让您了解如何做。公共类ValidationHandler:HttpOperationHandler{privatereadonlyHttpOperationDescription_httpOperationDescription;私有只读Uri_baseAddress;publicValidationHandler(HttpOperationDescriptionhttpOperationDescription,UribaseAddress){_httpOperationDescription=httpOperationDescription;_baseAddress=baseAddress;}protectedoverrideIEnumerableOnGetInputParameters(){returnnew[]{HttpParameter.RequestMessage};}protectedoverrideIEnumerableOnGetOutputParameters(){vartypes=_httpOperationDescription.InputParameters.Select(x=>x.ParameterType);返回types.Select(type=>newHttpParameter(type.Name,type));}protectedoverrideobject[]OnHandle(object[]input){varrequest=(HttpRequestMessage)input[0];varuriTemplate=_httpOperationDescription.GetUriTemplate();varuriTemplateMatch=uriTemplate.Match(_baseAddress,request.RequestUri);varvalidationResults=newList();//绑定来自uriTemplat的值eMatch.BoundVariablestoamodel//使用Validator.TryValidateObject进行验证并将结果添加到validationResults//使用BadRequesthttp状态代码抛出异常并将validationResults添加到消息中//返回一个对象数组,其中包含返回类型的实例来自OnGetOutputParmeters的有界值}}OnGetInputParameters的值告诉OnHandle方法期望的内容,OnGetOutputParameters告诉OnHandle方法的期望输出(稍后会被注入到服务中的方法中)然后你可以添加使用HttpConfiguration处理你的路由,如下所示:RouteTable.Routes.MapServiceRoute("MyResource",httpConfiguration);MSDN上发布了一个这样的示例,用于创建应该起作用的行为。您还可以使用Validator.ValidateObject手动调用验证器(或将其包装为扩展方法)并返回验证错误,这实际上就是该行为的作用。以上就是C#学习教程分享的全部内容:验证模型属性WCFWebAPI。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处:
