2014-10-31 25 views
0

我需要获得以下XML:装饰的Xml类名上的XmlSerializer

<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> 

如何重新命名的标签内容,以登录或注销?

非常感谢

回答

0

假设你知道所有可能的类型的请求,您可以使用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> 

这是你想要的吗?我排除了简单请求的通用性。