C# DataContract DataMember EmitDefaultValue=false still outp

本文关键字:false still outp EmitDefaultValue DataContract DataMember | 更新日期: 2023-09-27 18:19:32

我有一些非常简单的代码。

    //File Company.cs
    using System;
    using Sharpen;
    using System.Reflection;
    using System.Runtime.Serialization;
    namespace XPathTest
    {
        [DataContract(IsReference=true)]
        public class Company
        {
            [DataMember]
            public AList<Person> employees {get; set;}
            public Company ()
            {
                employees = new AList<Person>();
            }
        }
    }
    //File Employee.cs
    using System;
    using System.Reflection;
    using System.Runtime.Serialization;
    namespace XPathTest
    {
        [DataContract(IsReference=true)]
        public class Employee :  Person
        {
            public Employee ()
            {
            }
        }
    }

    //File Manager.cs
    using System;
    using Sharpen;
    using System.Reflection;
    using System.Runtime.Serialization;
    namespace XPathTest
    {
        [DataContract(IsReference=true)]
        public class Manager : Person
        {
            [DataMember(EmitDefaultValue=false)]
            public AList<Person> employees { get; set; }
            public Manager ()
            {
                employees = new AList<Person>();
            }
            public void AddEmployee(Person employee)
            {
                employees.Add (employee);
            }
        }
    }

    //File Person.cs
    using System;
    using System.Reflection;
    using System.Runtime.Serialization;
    namespace XPathTest
    {
        [DataContract(IsReference=true)]
        public class Person
        {
            [DataMember]
            public int SSNum { get; set; }
            [DataMember]
            public string name { get; set; }
            [DataMember(EmitDefaultValue=false)]
            public Person manager {get; set;}
            public Person ()
            {
            }
            public void SetManager(Person manager) 
            {
                this.manager = manager;
            }
        }
    }

//File Main.cs
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using XPathTest;
public class Test
{
    public static void Main()
    {
        // Read and write purchase orders.
        Test t = new Test();
    t.MarshalCompany ("po.xml");
    }
    public Company BuildCompany ()
    {
        Company company = new Company();
        Manager employee1 = new Manager();
        employee1.SSNum = 1337;
        employee1.name ="Jane Doe";
        company.employees.Add(employee1);
        Employee employee2 = new Employee();
        employee2.SSNum = 8008132;
        employee2.name = "John Smith";
        employee2.SetManager(employee1);
        company.employees.Add(employee2);
        Employee employee3 = new Employee();
        employee3.SSNum = 1138;
        employee3.name = "Anne Jones";
        employee3.SetManager(employee1);
        company.employees.Add(employee3);
        employee1.AddEmployee(employee2);
        employee1.AddEmployee(employee3);
        Manager manager1 = new Manager();
        manager1.SSNum = 314;
        manager1.name = "Boss Hog";
        //manager1.setManager(manager1);
        manager1.AddEmployee(employee1);
        company.employees.Add(manager1);
        return company;
    }
    public void MarshalCompany(string filename)
    {
        Company po = BuildCompany ();
        System.Runtime.Serialization.DataContractSerializer serializer = new DataContractSerializer (po.GetType ());
        using (FileStream stream = File.Create (filename)) 
        {
            serializer.WriteObject(stream, po);
        }
    }

我碰巧得到了这个输出。。。

<Company xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns="http://schemas.datacontract.org/2004/07/XPathTest" z:Id="i1">
<employees>
<Person i:type="Manager" z:Id="i2">
<SSNum>1337</SSNum>
<manager i:nil="true"/>
<name>Jane Doe</name>
<employees>
<Person i:type="Employee" z:Id="i3">
<SSNum>8008132</SSNum>
<manager i:type="Manager" z:Ref="i2"/>
<name>John Smith</name>
</Person>
<Person i:type="Employee" z:Id="i4">
<SSNum>1138</SSNum>
<manager i:type="Manager" z:Ref="i2"/>
<name>Anne Jones</name>
</Person>
</employees>
</Person>
<Person i:type="Employee" z:Ref="i3"/>
<Person i:type="Employee" z:Ref="i4"/>
<Person i:type="Manager" z:Id="i5">
<SSNum>314</SSNum>
<manager i:nil="true"/>
<name>Boss Hog</name>
<employees>
<Person i:type="Manager" z:Ref="i2"/>
</employees>
</Person>
</employees>
</Company>

为什么[DataMember(EmitDefaultValue=false)]属性不起作用?

输出显示类似的内容

<manager i:nil="true"/>

由于大小的原因,以及与jaxb在中输出的内容的兼容性,即使某些内容为null(没有元素),我也不想要它。

我在MSDN甚至其他stackoverflow页面上读到的所有内容都说这应该有效,但事实并非如此。如果有人能帮我弄清楚为什么零元素仍然存在,我将不胜感激。对我来说,如果你有来自"ngit"项目的Sharpen命名空间(对于Sharpen.AList,它只是Collections.List的包装器),那么发布在那里的代码就是工作代码。我最近做了很多java/c#。

我对此感兴趣的原因是,我有大量的数据,这些数据基本上是用Jaxb 2.2.7序列化的一些java类,我通过TCP将这些数据发送到一个C#客户端,该客户端在java中有类似的类。目标是将这些数据直接分解到c类中。不幸的是,我在jaxb中找不到为序列化的每个对象自然创建通用引用跟踪器的方法,并且不得不为我想要跟踪和引用的每个类手动编写@XmlAdapter。看起来DataContract很自然也很容易做到这一点。然而,JAXB不会在输出xml中引用null元素,我希望确保DataContract的内容模仿相同的行为。

谢谢。

C# DataContract DataMember EmitDefaultValue=false still outp

显然我遇到了这个bug,因为我使用的是Monoddevelop 3.0.3.2。

https://bugzilla.xamarin.com/show_bug.cgi?id=7999

谁能想到呢。我在2012年的VC中测试了它,它运行良好。单显影失败。