MVC4中XML和Json序列化程序的区别

时间:2013-09-25 11:14:22

标签: .net asp.net-mvc asp.net-mvc-4 xmlserializer jsonserializer

我发现今天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属性添加到类的每个属性,它也返回只读变量,但我真的不我想这样做。

2 个答案:

答案 0 :(得分:0)

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

datacontractserializer允许序列化只读属性。

答案 1 :(得分: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返回值的条件对调用者来说是未知的(即私有),因此无法序列化...

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