.NET WebAPI序列化k_BackingField Nastiness


86

当我序列化以下内容时:

[Serializable]
public class Error
{

    public string Status { get; set; }
    public string Message { get; set; }
    public string ErrorReferenceCode { get; set; }
    public List<FriendlyError> Errors { get; set; }
}

我得到这个令人作呕的烂摊子:

<ErrorRootOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance"   xmlns="http://schemas.datacontract.org/2004/07/Printmee.Api">
<_x003C_Errors_x003E_k__BackingField>
An exception has occurred. Please contact printmee support
</_x003C_Errors_x003E_k__BackingField>
<_x003C_LookupCode_x003E_k__BackingField>988232ec-6bc9-48f3-8116-7ff7c71302dd</_x003C_LookupCode_x003E_k__BackingField>
</ErrorRootOfstring>

是什么赋予了?我该如何使其漂亮?JSON响应还包含k_BackingField


Answers:


126

默认情况下,您既不需要使用[Serializable]也不[DataContract]使用Web API。

只需保持模型不变,Web API就会为您序列化所有公共属性。

仅当您想要对包含的内容有更多控制时,才可以使用修饰类,[DataContract]并包含要包含的属性[DataMember](因为DCS和JSON.NET均会解析这些属性)。

如果出于某种原因,您需要[Serializable]在类上使用(例如,出于某种原因将其序列化到内存流中,进行深层复制等),则必须同时使用这两个属性来防止后备字段名称:

[Serializable]
[DataContract]
public class Error
{
    [DataMember]
    public string Status { get; set; }
    [DataMember]
    public string Message { get; set; }
    [DataMember]
    public string ErrorReferenceCode { get; set; }
    [DataMember]
    public List<FriendlyError> Errors { get; set; }
}

6
就这样-我只需要删除[可序列化]。谢谢。
米卡2012年

谢谢菲利普,由于缓存原因必须保留属性。顺便说一句,我是您博客的狂热爱好者。
Stephen Patten

20
这太可怕了。为什么在序列化方面Microsoft永远做不到正确的事情?
克里斯·马里西奇

有一个更通用的解决方案,如下面我自己的回答所示。
JotaBe 2014年

也许序列化的问题是“正确”的定义,每个人都需要以自己的方式获取数据。
Luiz Felipe 2015年

94

还有一个更通用的解决方案:您可以将Json Serializer配置为忽略该[Serializable]属性,从而不必在类中更改属性。

您应该在应用程序启动时(即在Global.asaxApplication_Start事件中)更改此配置:

var serializerSettings =
  GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
var contractResolver =
  (DefaultContractResolver)serializerSettings.ContractResolver;
contractResolver.IgnoreSerializableAttribute = true;

您还可以对Json序列化进行其他更改,例如指定序列化日期的格式,以及进行其他许多操作。

这仅适用于Web API JSON序列化。应用程序中的其他序列化(Web API XML序列化,MVC JsonResult ...)将不受此设置的影响。


4
我喜欢此解决方案比在各处添加[DataContract]和[DataMember]属性要好得多。谢谢!!
Mark Good

1
不是您应该一直使用的东西,但这是一个巧妙的技巧。一种撬棍,可帮助您解决混乱的情况,因为您没有足够的钱来更改模型或深度重构代码库。
uygar.raf 2015年

没错,这不是最好的方法。但是,在某些情况下,重构不仅是一种奢侈,而且根本不可行。例如,如果代码库使用WCF或XML序列化,则它确实需要数据协定或XML序列化属性。您无法更改。幸运的是,JSON.NET非常强大:它确实支持数据协定,XML序列化及其自身的属性,并且您可以控制它如何使用它们进行序列化,甚至完全忽略它们。您甚至可以添加自己的实现。当然,我更喜欢保持简洁而没有属性。
JotaBe 2015年

这就是默认情况下应该如何工作!为什么我们要在序列化流中浪费后备场废话?
拜伦·惠特洛克

1
如果您使用的是Web api,并且目标是.net框架的第4版,则您需要更新Netwonsoft.Json软件包才能使其正常运行,即 Update-Package Newtonsoft.Json
pblack


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.