本文介绍了如何使用DataContractSerializer的创建XML与匹配我的已知类型的标签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的数据合同:

  [CollectionDataContract(NAME =MyStuff)
公共类MyStuff:收集&LT​​;对象> {}

[DataContract(名称为类型1)
[KnownType(typeof运算(类型1))]
公共类类型1
{
    [数据成员(名称为会员id)公众诠释编号{获得;组; }
}

[DataContract(NAME =2型)
[KnownType(typeof运算(类型2))]
公共类类型2
{
    [数据成员(名称为会员id)公众诠释编号{获得;组; }
}
 

这我序列化到XML如下:

  MyStuff PM =新MyStuff();

类型1 T1 =新类型1 {n = 111};
类型2 T2 =新的2型{n = 222};

pm.Add(T1);
pm.Add(T2);

XML字符串;

StringBuilder的serialXML =新的StringBuilder();
DataContractSerializer的dcSerializer =新的DataContractSerializer(typeof运算(MyStuff));
使用(XmlWriter的xWriter = XmlWriter.Create(serialXML))
{
    dcSerializer.WriteObject(xWriter,PM);
    xWriter.Flush();
    XML = serialXML.ToString();
}
 

生成的XML字符串看起来是这样的:

 < XML版本=1.0编码=UTF-16&GT?;
< MyStuff的xmlns:I =htt​​p://www.w3.org/2001/XMLSchema-instance
         的xmlns =htt​​p://schemas.datacontract.org/2004/07/>
    < anyType的我:TYPE =类型1>
        <会员id> 111 LT; /会员id>
    < / anyType的>
    < anyType的我:TYPE =2型>
        <会员id> 222< /会员id>
    < / anyType的>
< /我的资料GT;
 

有谁知道我怎样才能得到它,而不是用我已知类型的名称,而不是 anyType的的在XML标签?

我想它看起来是这样的:

 < XML版本=1.0编码=UTF-16&GT?;
< MyStuff的xmlns:I =htt​​p://www.w3.org/2001/XMLSchema-instance
         的xmlns =htt​​p://schemas.datacontract.org/2004/07/>
    <类型1>
        <会员id> 111 LT; /会员id>
    < /类型1>
    < 2型>
        <会员id> 222< /会员id>
    < / 2型>
< /我的资料GT;
 

解决方案

究竟为什么要这么做?

  [DataContract(名称为类型1)
[KnownType(typeof运算(类型1))]
公共类类型1
{
}
 

我不认为 KnownType 属性需要在这里 - 这将需要在多态的情况下:如果你有返回的方法基本类型键,可以返回一个派生类型类型1:在其位基本类型

如果您返回类型1 ,你会永远只能真的有类型1 作为类型,即knownType属性多余的。

第二个问题是这样的:

 公共类MyStuff:收集&LT​​;对象> {
 

如果你有对象的集合 - 这是潜在的东西的集合,在所有 - 所以序列化将使用的xs:anyType的来重新present了。

你能不能从基类中引入一个基类的类型,让你的集合,它的基本类型的集合,并从中获得你的两个不同的类型?

I have the following data contract:

[CollectionDataContract(Name="MyStuff")] 
public class MyStuff : Collection<object> {}

[DataContract(Name = "Type1")]
[KnownType(typeof(Type1))]
public class Type1
{
    [DataMember(Name = "memberId")] public int Id { get; set; }
}

[DataContract(Name = "Type2")]
[KnownType(typeof(Type2))]
public class Type2
{
    [DataMember(Name = "memberId")] public int Id { get; set; }
}

Which I serialize to xml as follows:

MyStuff pm = new MyStuff();

Type1 t1 = new Type1 { Id = 111 };
Type2 t2 = new Type2 { Id = 222 };

pm.Add(t1);
pm.Add(t2);

string xml;

StringBuilder serialXML = new StringBuilder();
DataContractSerializer dcSerializer = new DataContractSerializer(typeof(MyStuff));
using (XmlWriter xWriter = XmlWriter.Create(serialXML))
{
    dcSerializer.WriteObject(xWriter, pm);
    xWriter.Flush();
    xml = serialXML.ToString();
}

The resultant xml string looks like this:

<?xml version="1.0" encoding="utf-16"?>
<MyStuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://schemas.datacontract.org/2004/07/">
    <anyType i:type="Type1">
        <memberId>111</memberId>
    </anyType>
    <anyType i:type="Type2">
        <memberId>222</memberId>
    </anyType>
</MyStuff>

Does anyone know how I can get it to instead use the name of my known types rather than anyType in the xml tag?

I'm wanting it to look like this:

<?xml version="1.0" encoding="utf-16"?>
<MyStuff xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://schemas.datacontract.org/2004/07/">
    <Type1>
        <memberId>111</memberId>
    </Type1>
    <Type2>
        <memberId>222</memberId>
    </Type2>
</MyStuff>
解决方案

Why on earth are you doing this??

[DataContract(Name = "Type1")]
[KnownType(typeof(Type1))]
public class Type1
{
}

I don't think the KnownType attribute is needed here - it would be needed in polymorphism cases: if you have a method that returns BaseType and could return a derived type Type1 : BaseType in its place.

If you return Type1 and you'll only ever really have Type1 as the type, that knownType attribute is superfluous.

The second problem is this:

public class MyStuff : Collection<object> {

If you have a collection of object - it's a collection of potentially anything at all - so the serializer will use the xs:anyType to represent that.

Can't you introduce a base class type, make your collection a collection of that base type, and derive your two separate types from that base class?

这篇关于如何使用DataContractSerializer的创建XML与匹配我的已知类型的标签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 02:49