2014-10-31 18 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> 

這是你想要的嗎?我排除了簡單請求的通用性。