0

我发现今天 MVC4 使用的 XML 和 Json 序列化程序之间存在相当大的差异。

我试图返回一个看起来像这样的对象:

public class Person
{
  public string FirstName {get;set;}
  public string LastName {get;set;}
  public string FullName{ get{ return FirstName + " " + LastName }}
}

当客户端请求 json 作为结果时,我得到FirstNameLastNameFullName返回预期值。

但是,当客户端请求 XML 数据时,他只得到FirstNameLastName

在我看来这是非常糟糕的,因为这意味着客户端将根据他们请求的格式获得不同的数据。

这似乎是故意的,因为 Json 序列化程序的文档说默认包含只读属性,而对于 Xml 序列化程序,默认情况下它们被排除在外。

所以我的问题是:我如何更改 MVC4 使用的 Xml 序列化程序以默认包含那些只读的。我知道它可以做到,因为如果您将DataContract属性添加到类,并将DataMember属性添加到类的每个属性,它也会返回只读变量,但我真的不想这样做。

4

2 回答 2

0

首先,我推荐这篇文章:

http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#xml_readonly

因为它提供了 WebAPI/MVC 中序列化的出色概述,包括展示如何告诉 MVC 使用什么序列化程序(如果您决定实现自己的序列化程序来解决只读问题)

现在,如果你想使用默认的序列化器(DataContract 或 Xml),很遗憾你不能告诉它自动序列化只读属性;这是设计使然-如果您考虑一下,它就具有某种意义;因为 XML 序列化的典型用例是

  • 序列化类型 A
  • 通过电线发送/保存到磁盘
  • 在未来的某个时候再读一遍
  • 反序列化为A 类的实例

我想这是因为传统上(在有很多概念之前,您可能希望通过 HTTP 将这些数据发送到基于弱类型浏览器的语言)序列化只读属性几乎没有意义 - 因为你由于该字段是只读的,因此无法反序列化回原始类型!

当然,现在你可能想要这些是很有意义的,我相信 JSON 序列化程序的人在决定默认为 JSON 包含只读属性时已经考虑到这一点,因为这是更典型的用例不是序列化回强类型实例,而是动态类型化的 java 脚本对象。

即给定

 public class Foo
    {
        public int Bar { get; set; }
        public string BarName { get { return "This is Bar# " + Bar; } }
    }

让我们假设默认情况下 Xml 或 DataContract Serializer 产生了这个:

   <Foo>
     <Bar>10</Bar>
     <BarName>This is Bar# 10</BarName>
   </Foo>

您希望以下代码如何工作?

 var xs = new XmlSerializer(typeof(Foo));
 var y = xs.Deserialize(new StreamReader(@"C:\foo.xml")) as Foo;

BarName不抛出只读属性的异常?

不可设置属性的全部意义在于构成getter返回值的条件对于调用者来说是未知的(即私有的),因此不能被序列化......

因此DataContractandDataMembers允许您覆盖默认行为。

于 2013-10-01T13:41:37.163 回答
0

您必须使用 datacontractserializer 并使用 DataContract 属性标记您的实体,并且您希望使用 DataMember 序列化每个成员。

datacontractserializer 允许对只读属性进行序列化。

于 2013-09-25T12:05:32.850 回答