0

今天,我发现MVC4使用的XML和Json序列化程序之间存在着很大的不同。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属性添加到类的每个属性,它也会返回只读变量,但我真的不想这样做。

回答

0

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

datacontractserializer允许只读属性的序列化。

+0

重新阅读我的问题:我做**不**想用'DataContract/DataMember'属性标记所有的类就是为了这个。我想更改序列化程序中的设置以默认包含只读属性(就像Json序列化程序一样) –

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串行生产这种假设:

<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它允许您覆盖默认行为。

相关问题