在运行时性能的Web API序列化条件

编程入门 行业动态 更新时间:2024-10-27 22:26:27
本文介绍了在运行时性能的Web API序列化条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我期待在建设ASP.Net使用的WebAPI的API。

I am looking at building an API using WebAPI in ASP.Net.

我有一个要求,基于在 运行,而不是编译时的一些自定义逻辑有条件地排除在XML或JSON属性。

I have a requirement to conditionally exclude properties from the XML or JSON based on some custom logic at RunTime and not Compile Time.

我不得不删除从响应的XML或JSON,它是没有好只是包括空或空值的变量。

I have to remove the xml or json from the response, it is no good just including the tags with a null or empty value.

我已经试过各种方法,但没有去上班。

I have tried various approaches, none of which I seem to be able to get to work.

我曾尝试以下

委托处理程序 from这里

public class ResponseDataFilterHandler : DelegatingHandler { protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return base.SendAsync(request, cancellationToken) .ContinueWith(task => { var response = task.Result; //Manipulate content here var content = response.Content as ObjectContent; if (content != null && content.Value != null) { } //Or replace the content //response.Content = new ObjectContent(typeof(object), new object(), new MyFormatter()); return response; }); } }

当然,我可以在这里空的属性,但他们仍然会出现在响应。

Sure I can null properties out here, but they still appear in the response.

DataContractSurrogate 相似这个

public class MySurrogate: IDataContractSurrogate { public object GetCustomDataToExport(Type clrType, Type dataContractType) { return null; } public object GetCustomDataToExport(System.Reflection.MemberInfo memberInfo, Type dataContractType) { return null; } public Type GetDataContractType(Type type) { return null; } public object GetDeserializedObject(object obj, Type targetType) { return null; } public void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection<Type> customDataTypes) { } public object GetObjectToSerialize(object obj, Type targetType) { if (obj == null) return null; var type = obj.GetType(); type.GetProperties().ToList() .ForEach(prop => { try { var attr = prop.GetCustomAttributes(typeof(ConditionalDataMemberAttribute), false); if (attr.Any()) { var proptype = prop.PropertyType; //Set the property value to its default value prop.GetSetMethod().Invoke(obj, new[] { proptype.IsValueType ? Activator.CreateInstance(proptype) : null }); } } catch { } }); return obj; } public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData) { return null; } public System.CodeDom.CodeTypeDeclaration ProcessImportedType(System.CodeDom.CodeTypeDeclaration typeDeclaration, System.CodeDom.CodeCompileUnit compileUnit) { return null; } }

同样,我可以只空的属性了,我不能删除从输出的XML或JSON。

Again, I can just null the properties out, I cannot remove the xml or json from the output.

我有一个想法,我可以动态编译特定类与所需的属性然后使用DataContractSurrogate与我的新的动态编译的类的实例换出原来的实例 - 但我不喜欢它。

I have an idea where I can dynamically compile a specific class with the required attributes then use the DataContractSurrogate to swap out the original instance with an instance of my new dynamic compiled class - but I don't like it.

香港专业教育学院试图寻找的DataContractSerializer ,但它是密封的,所以我不能从中获得 - 我也看了反编译,并作出一些改变,但它再次使用了内部类如 DataContract - 我觉得我需要挂接到序列化,但我不知道如何

Ive tried looking at DataContractSerializer but it is sealed so I cant derive from it - i've also looked to decompile it and make some changes but again it uses internal classes such as DataContract - I feel I need to hook into the serialization but I don't know how to ?

推荐答案

好吧,我成功地做到这一点使用了一点什么,我已经做了,再加上一些在这里的建议,我也偶然发现的这个

Okay I managed to do this using a bit of what I had already done, plus some of the suggestions on here, I also stumbled upon this

首先,我们通过增加一个 DelegatingHandler 进入管道开始。

First we start by adding a DelegatingHandler into the pipeline.

config.MessageHandlers.Add(new ResponseDataFilterHandler());

和类本身

public class ResponseDataFilterHandler : DelegatingHandler { protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return base.SendAsync(request, cancellationToken) .ContinueWith(task => { var response = task.Result; var content = response.Content as ObjectContent; if (content != null && content.Value != null) { var isJson = response.RequestMessage.GetQueryNameValuePairs().Any(r => r.Key == "json" && r.Value == "true"); response.Content = new StringContent(Helper.GetResponseData(content.Value, isJson)); } return response; }); } }

然后我们有一个辅助类的方法获取新的序列化的字符串(这不是督促code; P)

Then we have a helper class method to get the new serialized string (this is not prod code ;p)

public static class Helper { public static string GetResponseData(object root,bool isJson) { string json = JsonConvert.SerializeObject(root, new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver()}); if (!isJson) { XmlDocument doc = JsonConvert.DeserializeXmlNode(json,"response"); json = doc.OuterXml; } return json; } }

和最后的 ContractReoslver

public class ShouldSerializeContractResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); property.ShouldSerialize = (i) => { //Your logic goes here var r = !property.PropertyName.StartsWith("block-ref"); return r; }; return property; } }

这一切的根源,通过JSON和皈依为xml如果需要的话,我的测试项目中,我使用一个查询字符串(JSON = TRUE)来指定,如果格式应JSON而不是XML。

this roots everything through Json and the converts to xml if required, for my test project I am using a querystring (json=true) to specify if the format should be json instead of xml.

更多推荐

在运行时性能的Web API序列化条件

本文发布于:2023-11-09 20:11:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1573310.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:性能   条件   序列化   API   Web

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!