【问题标题】:Decorate Xml ClassName on XmlSerializer在 XmlSerializer 上装饰 Xml ClassName
【发布时间】:2014-10-31 18:00:28
【问题描述】:

我需要获取以下xml:

<request id="1">
  <login>
    <username>username</username>
    <password>password</password>
  </login>
</request>

但是中间的xml可以换成另一种类型的请求,比如

<request id="1">
  <logout />
</request>

我尝试了以下方法:

[XmlRootAttribute(ElementName = "request", Namespace = "", IsNullable = false)]
public class Request<T>
{
    [XmlAttributeAttribute(AttributeName = "id", Namespace = "")]
    public string Id { get; set; }

    public T Content { get; set; }
}

[XmlTypeAttribute(TypeName = "login", AnonymousType = true)]
public class LoginRequest
{
    [XmlElementAttribute(ElementName = "username", Namespace = "")]
    public string Username;

    [XmlElementAttribute(ElementName = "password", Namespace = "")]
    public string Password;
}

[XmlTypeAttribute(TypeName = "logout", AnonymousType = true)]
public class LogoutRequest
{
}

但是当我使用序列化对象时

var serializer = new XmlSerializer(typeof(Request<LoginRequest>));

我得到了以下 xml:

<request id="1">
  <Content>
    <username>username</username>
    <password>password</password>
  </Content>
</request>

如何将标签内容重命名为登录或注销?

非常感谢

【问题讨论】:

    标签: c# attributes computer-science xmlserializer


    【解决方案1】:

    假设您知道所有可能的请求类型,您可以使用XmlElement(name, Type) 构造函数来覆盖特定类型的属性名称:

    [XmlRoot(ElementName = "request", Namespace = "", IsNullable = false)]
    public class Request
    {
        [XmlAttributeAttribute(AttributeName = "id", Namespace = "")]
        public string Id { get; set; }
    
        [XmlElement("login", Type = typeof(LoginRequestData))]
        [XmlElement("logout", Type = typeof(LogoutRequestData))]
        public BaseRequestData RequestData { get; set; }
    
        public TRequestData GetRequestData<TRequestData>() where TRequestData : BaseRequestData
        {
            return RequestData as TRequestData;
        }
    }
    
    public abstract class BaseRequestData
    {
    }
    
    public class LoginRequestData : BaseRequestData
    {
        [XmlElementAttribute(ElementName = "username", Namespace = "")]
        public string Username;
    
        [XmlElementAttribute(ElementName = "password", Namespace = "")]
        public string Password;
    }
    
    public class LogoutRequestData : BaseRequestData
    {
    }
    
    public class SomeUnknownRequestData : BaseRequestData
    {
    }
    

    并且,测试:

        public static void LoginRequestTest()
        {
            try
            {
                var request1 = new Request() { RequestData = new LoginRequestData() { Username = "foo", Password = "bar" } };
                var request2 = new Request() { RequestData = new LogoutRequestData() };
                var request3 = new Request() { RequestData = new SomeUnknownRequestData() };
    
                var xml1 = request1.GetXml();
                var xml2 = request2.GetXml();
                try
                {
                    var xml3 = request3.GetXml(); // Throws an exception.
                }
                catch (InvalidOperationException ex2)
                {
                    Debug.WriteLine(ex2.ToString());
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, ex.ToString()); // No assert
            }
        }
    

    xml1 看起来像:

    <?xml version="1.0" encoding="utf-16"?>
    <request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <login>
            <username>foo</username>
            <password>bar</password>
        </login>
    </request>
    

    xml2 看起来像:

    <?xml version="1.0" encoding="utf-16"?>
    <request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <logout />
    </request>
    

    这是你想要的吗?为简单起见,我消除了 Request 的通用性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多