我正在使用 MVC 4 Web API 和 asp.net web 表单 4.0 来构建一个 rest API。它工作得很好:
[HttpGet]
public HttpResponseMessage Me(string hash)
{
HttpResponseMessage httpResponseMessage;
List<Something> somethings = ...
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK,
new { result = true, somethings = somethings });
return httpResponseMessage;
}
现在我需要阻止一些属性被序列化。我知道我可以在列表上使用一些 LINQ 并只获取我需要的属性,通常这是一个很好的方法,但在目前的情况下,something
对象太复杂了,我需要在不同的方法中使用不同的属性集,所以在运行时,更容易标记要忽略的每个属性。
有没有办法做到这一点?
10 回答
我迟到了,但是一个匿名的对象可以解决这个问题:
尝试使用
IgnoreDataMember
属性ASP.NET Web API 使用Json.Net作为默认格式化程序,因此如果您的应用程序仅使用 JSON 作为数据格式,则可以使用
[JsonIgnore]
忽略属性进行序列化:但是,这种方式不支持 XML 格式。因此,如果您的应用程序必须支持更多 XML 格式(或仅支持 XML),而不是使用
Json.Net
,则应使用支持 JSON 和 XML 的[DataContract]
:为了更好地理解,您可以阅读官方文章。
根据 Web API 文档页面ASP.NET Web API 中的 JSON 和 XML 序列化明确阻止对属性进行序列化,您可以使用
[JsonIgnore]
作为 Json 序列化程序,或[IgnoreDataMember]
作为默认 XML 序列化程序。但是在测试中我注意到
[IgnoreDataMember]
阻止了 XML 和 Json 请求的序列化,因此我建议使用它而不是装饰具有多个属性的属性。您可以采用“opt-in”方法,而不是让所有在默认情况下被序列化。在此方案中,只允许序列化您指定的属性。您可以使用System.Runtime.Serialization命名空间中的DataContractAttribute和DataMemberAttribute执行此操作。
DataContactAttribute
应用于类,DataMemberAttribute
应用于要序列化的每个成员:我敢说这是一种更好的方法,因为它会迫使你做出明确的决定,决定通过序列化会做什么或不会做什么。它还允许您的模型类自己生活在一个项目中,而不依赖于 JSON.net 只是因为其他地方恰好用 JSON.net 序列化它们。
这对我有用:创建一个自定义合约解析器,它有一个名为 AllowList of string array type 的公共属性。在您的操作中,根据操作需要返回的内容修改该属性。
**1.**创建自定义合约解析器:
**2.**使用自定义合同解析程序
这种方法允许我为特定请求 allow/disallow 而不是修改类定义。如果您不需要 XML 序列化,请不要忘记在
App_Start\WebApiConfig.cs
中关闭它,否则如果客户端请求 xml 而不是 json,您的 API 将返回被阻止的属性。我将告诉你两种方法来实现你想要的:
第一种方法:使用 JsonProperty 属性装饰您的字段,以便在该字段为空时跳过该字段的序列化.
第二种方式:如果您正在与一些复杂的场景进行协商,那么您可以使用 Web Api 约定(“ShouldSerialize”),以便根据某些特定逻辑跳过该字段的序列化.
WebApi 使用 JSON.Net 并使用反射进行序列化,因此当它检测到(例如)ShouldSerializeFieldX()方法时,名称为 FieldX 的字段将不会被序列化。
几乎与 greatbear302 的答案相同,但我根据请求创建了 ContractResolver。
编辑:
它不能作为每个请求的 expected(isolate 解析器工作)。我将使用匿名对象。
您可以使用 AutoMapper 并使用
.Ignore()
映射,然后发送映射对象出于某种原因
[IgnoreDataMember]
并不总是对我有用,我有时会得到StackOverflowException
(或类似的)。所以相反(或者另外)我开始在Objects
中使用Objects
这样的模式看起来像我的 API:所以基本上我传入一个
JObject
并在收到它之后将其转换为由 built-in 序列化器引起的 aviod 问题,这有时在解析对象时会导致无限循环。如果有人知道这是一个坏主意的原因,请告诉我。
值得注意的是,EntityFramework Class-property 的以下代码会导致问题(如果两个类引用 each-other):