首页 > 解决方案 > XmlSerializer 将命名空间添加到所有元素。如何排除这个?

问题描述

介绍

使用以下代码,我想创建下面提到的 XML 输出:但是,当我尝试使用以下代码(dotnet fiddle)执行此操作时:

using System;
using System.Xml.Serialization;
using System.IO;
using System.Text;

public class Program
{
    [XmlRoot(ElementName = "OtpAlgorithm", Namespace = "http://www.verisign.com/2006/08/vipservice")]
    public class OtpAlgorithm
    {
        [XmlAttribute(AttributeName = "type")]
        public string Type { get; set; }
    }

    [XmlRoot(ElementName = "DeviceId", Namespace = "http://www.verisign.com/2006/08/vipservice")]
    public class DeviceId
    {
        [XmlElement(ElementName = "Model", Namespace = "http://www.verisign.com/2006/08/vipservice")]
        public string Model { get; set; }
    }

    [XmlRoot(ElementName = "ClientInfo", Namespace = "http://www.verisign.com/2006/08/vipservice")]
    public class ClientInfo
    {
        [XmlElement(ElementName = "platform", Namespace = "http://www.verisign.com/2006/08/vipservice")]
        public string Platform { get; set; }
    }

    [XmlRoot(ElementName = "Extension", Namespace = "http://www.verisign.com/2006/08/vipservice")]
    public class Extension
    {
        [XmlElement(ElementName = "ClientInfo", Namespace = "http://www.verisign.com/2006/08/vipservice")]
        public ClientInfo ClientInfo { get; set; }
        [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
        public string Type { get; set; }
        [XmlAttribute(AttributeName = "vip", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Vip { get; set; } = "http://www.verisign.com/2006/08/vipservice";
    }

    [XmlRoot(ElementName = "GetSharedSecret", Namespace = "http://www.verisign.com/2006/08/vipservice")]
    public class GetSharedSecretRequest
    {
        [XmlElement(ElementName = "TokenModel", Namespace = "http://www.verisign.com/2006/08/vipservice")]
        public string TokenModel { get; set; }
        [XmlElement(ElementName = "OtpAlgorithm", Namespace = "http://www.verisign.com/2006/08/vipservice")]
        public OtpAlgorithm OtpAlgorithm { get; set; }
        [XmlElement(ElementName = "DeviceId", Namespace = "http://www.verisign.com/2006/08/vipservice")]
        public DeviceId DeviceId { get; set; }
        [XmlElement(ElementName = "Extension", Namespace = "http://www.verisign.com/2006/08/vipservice")]
        public Extension Extension { get; set; }
        [XmlAttribute(AttributeName = "xmlns")]
        public string Xmlns { get; set; } = "http://www.verisign.com/2006/08/vipservice";
        [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Xsi { get; set; } = "http://www.w3.org/2001/XMLSchema-instance";
    }

    public static void Main()
    {
        var test = new GetSharedSecretRequest()
        {
            TokenModel = "Test",
            OtpAlgorithm = new OtpAlgorithm()
            {
                Type = "AlgorithmTest"
            },
            DeviceId = new DeviceId()
            {
                Model = "Test Model"
            },
            Extension = new Extension()
            {
                ClientInfo = new ClientInfo()
                {
                    Platform = "Test Plaftorm"
                },
                Type = "Another Test Type"
            }
        };

        var serialized = Serialize(test);

        //Basically this will fix it, but is ofcourse not a very nice solution:
        //serialized = serialized.Replace("vip:", "");

        Console.WriteLine(serialized);

        if (serialized.Contains("vip:") || !serialized.Contains("<Extension xsi:type=\"Another Test Type\" xmlns:vip=\"http://www.verisign.com/2006/08/vipservice\">"))
        {
            Console.WriteLine("Test failed :(");    
        }
        else
        {
            Console.WriteLine("Succeeded :)");  
        }
    }

    public static string Serialize<T>(T obj)
    {
        var serializer = new XmlSerializer(typeof(T));
        using (var memstream = new MemoryStream())
        {
            serializer.Serialize(memstream, obj);
            return Encoding.UTF8.GetString(memstream.GetBuffer());
        }
    }
}

我想生成的 XML 输出:

<?xml version="1.0"?>
<GetSharedSecret xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.verisign.com/2006/08/vipservice">
  <TokenModel>Test</TokenModel>
  <OtpAlgorithm type="AlgorithmTest" />
  <DeviceId>
    <Model>Test Model</Model>
  </DeviceId>
  <Extension xsi:type="Another Test Type" xmlns:vip="http://www.verisign.com/2006/08/vipservice">
    <ClientInfo>
      <platform>Test Plaftorm</platform>
    </ClientInfo>
  </Extension>
</GetSharedSecret>

但相反,我的代码生成了这个:

<?xml version="1.0"?>
<GetSharedSecret xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.verisign.com/2006/08/vipservice">
  <TokenModel>Test</TokenModel>
  <OtpAlgorithm type="AlgorithmTest" />
  <DeviceId>
    <Model>Test Model</Model>
  </DeviceId>
  <Extension xsi:type="Another Test Type" xmlns:vip="http://www.verisign.com/2006/08/vipservice">
    <vip:ClientInfo>
      <vip:platform>Test Plaftorm</vip:platform>
    </vip:ClientInfo>
  </Extension>
</GetSharedSecret>

有没有办法删除vip:扩展类中项目前面的?

我发现的唯一一件事是删除了 VIP 属性的命名空间:

[XmlAttribute(AttributeName = "vip", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Vip { get; set; } = "http://www.verisign.com/2006/08/vipservice";

已删除命名空间:

[XmlAttribute(AttributeName = "vip")]
public string Vip { get; set; } = "http://www.verisign.com/2006/08/vipservice";

然而,这会导致 XML 输出不再包含命名空间。这也是错误的。

问题

有人知道如何解决这个问题吗?我创建了一个dotnet fiddle来调试问题。

标签: c#.netxml

解决方案


推荐阅读