在XmlSerializer上装饰Xml ClassName
本文关键字:Xml ClassName XmlSerializer | 更新日期: 2023-09-27 18:28:34
我需要获得以下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>
如何将标记Content重命名为登录或注销?
非常感谢
假设您知道所有可能的请求类型,您可以使用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>
这是你想要的吗?为了简单起见,我去掉了请求的通用性。