[英]Serialization to XML using REST and WCF
我在使用REST并将响应作为XML返回时遇到问题。 我已经从模板创建了基本服务,一切看起来都不错但是当我想序列化我的类并将其作为响应返回时,服务返回其他内容。
看一看:
[WebHelp(Comment = "Sample description for DoWork")]
[WebInvoke(UriTemplate = "DoWork")]
[OperationContract]
public SampleResponseBody DoWork(SampleRequestBody request)
{
//TODO: Change the sample implementation here
return new SampleResponseBody()
{
Value = String.Format("Sample DoWork response: '{0}'", request.Data)
};
}
[WebHelp(Comment = "Returns order state based on client and order number")]
[WebInvoke(UriTemplate = "OrderStatus")]
[OperationContract]
public order_status OrderStatus(q_order_status request)
{
return new order_status()
{
error_id = 0,
client_acr = "client",
order_acr = "order"
};
}
第一种方法来自模板,第二种方法是我的。 返回结构如下所示:
public class SampleResponseBody
{
[DataMember]
public string Value { get; set; }
}
public class q_order_status
{
public string client_acr;
public string order_acr;
}
[DataContract]
[XmlSerializerFormat]
public class order_status
{
[XmlAttribute]
public int error_id;
[XmlElement]
public string error_desc;
[XmlElement]
public string order_acr;
[XmlElement]
public string client_acr;
}
编辑:
当我在REST工具包的帮助页面上时,我得到这个作为两个方法的示例响应是错误的(我不应该为第二个方法得到这个):
<SampleResponseBody>
<Value>String content</Value>
</SampleResponseBody>
当我像这样调用第一种方法:
User-Agent: Fiddler
Host: ipv4.fiddler:4617
Content-Type: text/xml
Content-Length: 63
<SampleRequestBody>
<Data>bla bla</Data>
</SampleRequestBody>
我收到:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Date: Wed, 30 Sep 2009 09:41:20 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Content-Length: 141
Connection: Close
<SampleResponseBody xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Value>Sample DoWork response: 'bla bla'</Value></SampleResponseBody>
这没关系。
我打电话给第二种方法是这样的:
User-Agent: Fiddler
Host: ipv4.fiddler:4617
Content-Type: text/xml
Content-Length: 115
<q_order_status>
<client_acr>String content</client_acr>
<order_acr>String content</order_acr>
</q_order_status>
我得到这个:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Date: Wed, 30 Sep 2009 09:44:18 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: application/xml; charset=utf-8
Content-Length: 67
Connection: Close
<order_status xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
它应该返回一个序列化为类order_status
XML实例有什么问题?
提前致谢。
编辑后:好的,问题是[OperationContract]
没有触发XmlSerializer
。 必须在[OperationContract]
之后插入[XmlSerializerFormat]
以覆盖默认的DataContractSerializer
。
使用WCF REST入门工具包,您应该能够创建一个返回XElement
作为其返回值的方法:
[WebHelp(Comment = "Returns order state based on client and order number")]
[WebInvoke(UriTemplate = "OrderStatus")]
[OperationContract]
public XElement OrderStatus(q_order_status request)
{
.....
}
在这种情况下,您的方法实现可能如下所示:
public XElement OrderStatus(q_order_status request)
{
return new XElement("q_order_status",
new XAttribute("error_id", 0),
new XElement("client_acr", "client acr value"),
new XElement("order_acr", "order acr value")
);
}
这将返回一个这样的XML片段:
<q_order_status error_id="0">
<client_acr>client acr value</client_acr>
<order_acr>order acr value</order_acr>
</q_order_status>
这样,任何事情都是可能的 - 完全取决于你如何以及如何在XML结构方面创建。
渣
我会说q_order_status应该用[DataContract]属性进行修饰,并且他的所有成员(以及order_status的成员)都应该用[DataMember]属性进行修饰。 或者你是故意忽略这些?
你可以试试这个order_status代码:
[DataContract]
public class order_status
{
[DataMember]
public int error_id;
[DataMember]
public string error_desc;
[DataMember]
public string order_acr;
[DataMember]
public string client_acr;
}
旁注:我还建议您遵循类和成员的.NET命名约定,PascalCase和没有下划线。 如果限制为给定的xml名称,则可以使用DataContract / DataMember属性的Name成员来定义xml名称。 (例如:[DataContract(Name =“order_status”)]公共类OrderStatus)。 ;)
这个问题(和最后的编辑)帮助我们解决了类似的问题。 我们发现,如果我们的WCF服务改为使用XmlSerializerFormat,我们可以轻松地反序列化我们的对象,而不是使用DataContract / DataMember属性和使用(默认)DataContractSerializer来装饰数千个数据元素。
对于那些需要一个例子的人:
[System.ServiceModel.ServiceContract]
public interface IRestService
{
[System.ServiceModel.OperationContract]
// Added this attribute to use XmlSerializer instead of DataContractSerializer
[System.ServiceModel.XmlSerializerFormat(
Style=System.ServiceModel.OperationFormatStyle.Document)]
[System.ServiceModel.Web.WebGet(
ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Xml,
UriTemplate = "xml/objects/{myObjectIdentifier}")]
MyObject GetMyObject(int myObjectIdentifier);
}
这就是我们反序列化对象的方式:
public static T DeserializeTypedObjectFromXmlString<T>(string input)
{
T result;
try
{
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(T));
using (System.IO.TextReader textReader = new System.IO.StringReader(input))
{
result = (T)xs.Deserialize(textReader);
}
}
catch
{
throw;
}
return result;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.