【问题标题】:.NET WebAPI Serialization k_BackingField Nastiness.NET WebAPI 序列化 k_BackingField Nastiness
【发布时间】:2012-09-08 20:50:38
【问题描述】:

当我序列化以下内容时:

[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

【问题讨论】:

标签: serialization asp.net-web-api


【解决方案1】:

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

【讨论】:

  • 就是这样——我只需要删除 [Serializable]。谢谢。
  • 感谢 Filip,由于缓存的原因,必须保留属性。顺便说一句,我是你博客的忠实粉丝。继续加油!
  • 这太可怕了。为什么微软EVER在序列化方面不能做任何正确的事情?
  • 有一个更通用的解决方案,正如我在下面自己的答案中所示。
  • 也许序列化的问题在于“正确”的定义,每个人都需要数据。
【解决方案2】:

有一个更通用的解决方案:您可以配置 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...)不会受此设置影响。

【讨论】:

  • 我更喜欢这个解决方案,而不是到处添加 [DataContract] 和 [DataMember] 属性。谢谢!!
  • 不是你应该一直使用的东西,但这是一个巧妙的技巧。一种撬棍,可帮助您解决无法更改模型或深入重构代码库的混乱情况。
  • 你说得对,这不是最好的方法。然而,在某些情况下,重构不仅是一种奢侈,而且根本不可行。例如,如果代码库使用 WCF 或 XML 序列化,它确实需要数据协定或 XML 序列化属性。你无法改变这一点。幸运的是 JSON.NET 非常强大:它确实支持 Data Contract、XML 序列化和它自己的属性,您可以控制它如何使用它们进行序列化,甚至完全忽略它们。您甚至可以添加自己的实现。当然,我更喜欢保持没有属性的干净类。
  • 这是它默认的工作方式!为什么我们在序列化流中使用 wabt backingfield 废话?
  • 如果您使用 web api 并且目标是 .net 框架的版本 4,那么您需要更新 Netwonsoft.Json 包才能使其正常工作,即Update-Package Newtonsoft.Json
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    [DataContract] 属性对我不起作用,所以它不是一个选项。

    XmlSerializer ignores [XmlAttribute] in WebApi

    上述解决方案为我解决了。

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

    【讨论】:

      猜你喜欢
      • 2019-04-08
      • 2012-05-20
      • 1970-01-01
      • 2021-06-27
      • 2016-10-18
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多