.NET WebAPI序列化k_BackingField Nastiness

时间:2012-09-08 20:50:39

标签: serialization asp.net-web-api

当我序列化以下内容时:

[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

4 个答案:

答案 0 :(得分:121)

默认情况下,您不需要同时使用[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; }
}

答案 1 :(得分:85)

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

您应该在应用程序启动时更改此配置,即在Global.asax Application_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 ...)不会受此设置的影响。

答案 2 :(得分:2)

尝试使用DataContract而不是Serializable来标记您的类。有关原因的详细信息,请查看此good blog post on serializing automatic properties.

答案 3 :(得分:0)

[DataContract]属性对我不起作用,因此不是一种选择。

XmlSerializer ignores [XmlAttribute] in WebApi

以上分辨率为我解决了

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;