.net - 使用 DataContractSerializer 和 XmlSerializer 进行 XML 序列化

标签 .net wcf web-services xml-serialization

我有 2 个服务引用 (WCF)。

  • 第一个 Visual Studio 使用 DataContractSerializer 生成代码
  • 第二个,Visual Studio使用XmlSerializer生成代码

我无法更改网络服务器端的任何内容。

因此,我正在创建一个对象,该对象聚合来自两个引用的对象。

如何序列化此对象,使其遵守 DataContractSerializer 和 XmlSerializer 的序列化规范。 如果我使用 DataContractSerializer,我将像这样序列化引用 2 中的每个字段

<dataField>

而不是

<data>

因为它默认只序列化私有(private)字段(??)

如果我使用 XmlSerializer,引用 2 中的每个字符串数组都会像这样进行序列化

<myArray>
<string>test</string>
<string>test</string>
</myArray>

而不是

<myArray>
<url>test</url>
<url>test</url>
</myArray>

因为它忽略了 CollectionDataContractAttribute 属性,该属性指定如何序列化数组中的每个项目。

那么你的解决方案是什么?

我的第一个解决方案是将它们全部添加为良好的网络引用,但也许有一些不错的解决方案。

编辑:

这里是来自 1/Web 服务的类型声明(datcontract、wcf 样式)

    [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="productInformations", Namespace="http://abcedf.net/")]
[System.SerializableAttribute()]
public partial class productInformations : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged {

最佳答案

第一个问题:由于“添加Web引用”生成的类型被装饰为[Serializable]默认情况下, DataContractSerializer 使用的可序列化模型是所有字段(公共(public)或非公共(public))都被序列化。如果用 [DataContract] 修饰类型以及您想要使用 [DataMember] 序列化的成员(属性) 。一个类型可以毫无问题地具有两个序列化器的属性,如下所示。

public class StackOverflow_7348240
{
    [Serializable]
    [DataContract(Name = "myRoot", Namespace = "")]
    [XmlRoot(ElementName = "myRoot", Namespace = "")]
    public class MyType
    {
        private string dataField;

        [XmlElement(ElementName = "data")]
        [DataMember(Name = "data")]
        public string Data
        {
            get { return this.dataField; }
            set { this.dataField = value; }
        }
    }

    public static void Test()
    {
        MyType obj = new MyType { Data = "hello world" };

        MemoryStream ms = new MemoryStream();
        new DataContractSerializer(obj.GetType()).WriteObject(ms, obj);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));

        ms.SetLength(0);
        new XmlSerializer(obj.GetType()).Serialize(ms, obj);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }
}

对于第二个问题,如果集合类型是另一个对象的成员,您还可以添加适当的属性(这次是用于 XML 序列化的属性),即 [XmlArray] (指定集合名称)和 [XmlArrayItem] (指定项目名称),并且您可以以相同的方式序列化相同的类型,如下面的示例所示。

public class StackOverflow_7348240_b
{
    [DataContract(Name = "myRoot", Namespace = "")]
    [XmlRoot(ElementName = "myRoot", Namespace = "")]
    public class MyType
    {
        [DataMember(Name = "myArray")]
        [XmlArray(ElementName = "myArray")]
        [XmlArrayItem(ElementName = "url")]
        public MyArray myArray;
    }

    [CollectionDataContract(Name = "myArray", Namespace = "", ItemName = "url")]
    [XmlType(Namespace = "")]
    [XmlRoot(ElementName = "myArray", Namespace = "")]
    public class MyArray : List<string>
    {
    }

    public static void Test()
    {
        MyType obj = new MyType { myArray = new MyArray { "one", "two" } };

        MemoryStream ms = new MemoryStream();
        new DataContractSerializer(obj.GetType()).WriteObject(ms, obj);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));

        ms.SetLength(0);
        new XmlSerializer(obj.GetType()).Serialize(ms, obj);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }
}

更新

我知道您想“手动”合并类型,但根据评论,情况并非如此。在这种情况下,如果您想同时使用添加 Web 引用 (AWR) 和添加服务引用 (ASR),那么您需要回退到通用序列化程序,即 XmlSerializer 。 AWR总是使用XmlSerializer (XS),而 ASR 可以同时使用该和 DataContractSerializer (DCS)。 DCS 是 ASR 的默认设置,但您可以将其更改为使用另一种。您有两个选择:

  • 使用 svcutil.exe(而不是 ASR),并传递/serializer:XmlSerializer 命令行
  • 添加服务引用后,打开Reference.svcmap文件(您可能需要选中项目的“显示所有文件”选项),然后更改选项<Serializer>来自AutoXmlSerializer ,然后选择“更新服务引用”。

关于.net - 使用 DataContractSerializer 和 XmlSerializer 进行 XML 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7348240/

相关文章:

c# - ASP.NET MVC Helpers,将两个对象 htmlAttributes 合并在一起

c# - 任何列中 DataGridView 标题中的复选框

android - 将数据从 Android 传输到 MS SQL Server

WCF 无法与权限建立 SSL/TLS 安全通道的信任关系

java - 在过滤器中设置授权 header

web-services - Weblogic 10.3 WebService 一种方式 SSL HTTP 401 : unauthorized

c# - 已发布的控制台应用程序上没有 .NET Core 2.0 应用程序设置

.net - 以编程方式获取 GPU 利用率

javascript - 从 javascript 调用 WCF 后显示服务名称未定义

c# - 找不到 Restful Web 服务端点