我有一个WCF服务,它接受一个字符串作为其一个操作契约的参数。但是该字符串中包含xml内容。
我需要将其转换为标记为DataContract
的类,但不会暴露给外界。
我需要使用DataContractSerializer
,因为类成员将[DataMember]
属性设置为其他名称。例如:属性Phone
的DataMember名称设置为"Telephone"
,所以当我使用普通的序列化程序反序列化xmldocument时,我得到一个错误,因为反序列化器会查找Phone
元素不存在。
如何使用XmlDocument
反序列化DataContractSerializer
?但有一个限制是我无法将xmldocument保存到文件中。
编辑:使用DataContractSerializer
here.
我的客户代码:
string xmldata = "<Customer> +
System.Environment.NewLine+
"<Age>1</Age>"+
System.Environment.NewLine+
"<BirthDate>1900-01-01T01:01:01.0000000-05:00</BirthDate>" +
System.Environment.NewLine+
"<FistName>John</FistName>"+
System.Environment.NewLine +
"<LastName>Doe</LastName>" +
System.Environment.NewLine +
"</Customer>";
doc.LoadXml(xmldata);
Service1Client a = new Service1Client();
a.GetData(doc.OuterXml.ToString());
我的服务代码:
public string GetData(string per)
{
string xmldata = per;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmldata);
XmlDemo.Person a = Person.Create();
DataContractSerializer ser = new DataContractSerializer(a.GetType());
StringWriter stringWriter = new StringWriter();
XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
xmlDoc.WriteTo(xmlWriter);
MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(stringWriter.ToString()));
stream.Position = 0;
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
Person myContact = (Person)ser.ReadObject(reader, true);
return string.Empty;
}
我的DataContract:
[Serializable]
[DataContract(Name = "Customer")]
public class Person
{
private Person() {}
[DataMember(Name = "FistName")]
public string FName { get; set; }
[DataMember(Name = "LastName")]
public string LName { get; set; }
[DataMember(Name = "Age")]
public int Age { get; set; }
[DataMember(Name = "BirthDate")]
public DateTime DOB { get; set; }
public static Person Create()
{
return new Person();
}
}
我在Person myContact =(Person)ser.ReadObject(reader,true)中收到此错误;
Error in line 1 position 11. Expecting element 'Customer' from namespace 'http://schemas.datacontract.org/2004/07/XmlDemo'.. Encountered 'Element' with name 'Customer', namespace ''.
答案 0 :(得分:3)
从字符串直接反序列化
MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes("<myXml />"));
stream.Position = 0;
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
MyContact myContact = (MyContact)ser.ReadObject(reader, true);
从XmlDocument反序列化
StringWriter stringWriter = new StringWriter();
XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
xmlDoc.WriteTo(xmlWriter);
MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(stringWriter.ToString()));
stream.Position = 0;
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
MyContact myContact = (MyContact)ser.ReadObject(reader, true);
答案 1 :(得分:1)
此外,虽然您尚未将要将此XML反序列化到其中的DataContract公开,但您几乎已经通过公开XML来完成此操作。这在很大程度上是同样的效果。因此,您应该创建一个没有与之关联的行为的DataContract类,然后在ServiceContract中公开它。如果您需要在内部将其用作具有行为的类中的数据,则将数据复制到您从未公开的内部类的新实例中。
我仍然建议你通过将XML复制到字符串中来阻止这种愚蠢。仍然,根据您发布的代码和例外情况:
为什么这样做
XmlDemo.Person a = Person.Create();
然后在反序列化时将其擦除?
XmlDemo.Person a;
就足够了。然后使用typeof(XmlDemo.Person)而不是a.GetType()。
另外,你发布的Person类与“XmlDemo.Person”类完全相同吗?我非常想知道命名空间的来源。要消除我的不确定性,请尝试将[DataContract]属性更改为Namespace = String.Empty(或者Namespace = null)。
最后,你有没有听说过那个没有在实现IDisposable的类实例上调用Dispose的开发人员?