带有C#对象的前缀和名称空间
本文关键字:空间 前缀 对象 带有 | 更新日期: 2023-09-27 18:26:30
我正在尝试创建一个POST函数,该函数将C#类对象串行化为XML。
我遇到的最大困难是向子根元素的子元素添加名称空间前缀,因此在本例中,仅contact
子元素。
我似乎能够将前缀添加到contact
的子元素上的唯一方法是通过SerializerNamespace
类添加它们,但我只能将其附加到根元素CreateContact
。
我怎样才能做到这一点?
当前生成的XML:
<?xml version='"1.0'"?>
<CreateContact xmlns:a="http://foo.co.uk/Contact" xmlns="http://foo.co.uk">
<a:contact>
<a:Email>stest@gmail.com</a:Email>
<a:FirstName>Simon</a:FirstName>
<a:LastName>Test</a:LastName>
<a:Phone>09088408501</a:Phone>
<a:Title>Mr</a:Title>
</a:contact>
</CreateContact>
系列化功能:
public static void CreateContact(Contact contact)
{
string tmp = url;
string xml = "";
string result = "";
XmlDocument xd = new XmlDocument();
var cc = new CreateContact();
cc.contact = contact;
var xs = new XmlSerializer(cc.GetType());
XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
xsn.Add("a", "http://foo.co.uk/Contact");
using (MemoryStream ms = new MemoryStream())
{
xs.Serialize(ms, cc, xsn);
ms.Position = 0;
xd.Load(ms);
xml = xd.InnerXml;
}
using (WebClient web = new WebClient())
{
web.Credentials = new NetworkCredential(username, password);
web.Headers.Add("Content-Type", "application/xml");
try
{
result = web.UploadString(tmp, "POST", xml);
}
catch (WebException ex)
{
}
}
}
XML类构造:
[Serializable()]
[XmlRoot(ElementName = "CreateContact", Namespace = "http://foo.co.uk")]
public class CreateContact
{
[XmlElement(ElementName = "contact", Namespace = "http://foo.co.uk/Contact")]
public Contact contact { get; set; }
}
[DataContract(Name = "Contact", Namespace = "http://foo.co.uk/Contact")]
[XmlType("a")]
public class Contact
{
[XmlElement(ElementName = "Email", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Email")]
public string Email { get; set; }
[XmlElement(ElementName = "FirstName", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "FirstName")]
public string Firstname { get; set; }
[XmlElement(ElementName = "LastName", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "LastName")]
public string Lastname { get; set; }
[XmlElement(ElementName = "Phone", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Phone")]
public string Phone { get; set; }
[XmlElement(ElementName = "Title", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Title")]
public string Title { get; set; }
}
所需的XML:
<?xml version='"1.0'"?>
<CreateContact xmlns="http://foo.co.uk">
<contact xmlns:a="http://foo.co.uk/Contact">
<a:Email>stest@gmail.com</a:Email>
<a:FirstName>Simon</a:FirstName>
<a:LastName>Test</a:LastName>
<a:Phone>09088408501</a:Phone>
<a:Title>Mr</a:Title>
</contact>
</CreateContact>
正如注释中所暗示的,产生差异的原因是contact
应该在名称空间http://foo.co.uk
中,而不是http://foo.co.uk/Contact
中。
顺便说一句,还有一些进一步的评论:
- 您可能不需要
DataMember
属性,除非您在其他地方使用DataContractSerializer
- 大多数
Xml*
属性在这里是多余的,可以通过继承XmlRoot
来删除或合并 - 如果您只需要XML字符串,那么最好串行化为
StringWriter
,而不是流,然后加载到DOM中以获取文本(如果您需要XML声明来指定utf-8
,请参阅此问题)
因此,您将得到如下XML:
var xsn = new XmlSerializerNamespaces();
xsn.Add("a", "http://foo.co.uk/Contact");
var xs = new XmlSerializer(typeof(CreateContact));
using (var stringWriter = new StringWriter())
{
xs.Serialize(stringWriter, cc, xsn);
xml = stringWriter.ToString();
}
您的类定义为:
[XmlRoot(ElementName = "CreateContact", Namespace = "http://foo.co.uk")]
public class CreateContact
{
[XmlElement(ElementName = "contact")]
public Contact Contact { get; set; }
}
[XmlRoot("contact", Namespace = "http://foo.co.uk/Contact")]
public class Contact
{
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Title { get; set; }
}
完整的例子见这个小提琴。