有一个远程服务,我正在尝试使用SOAP通过http POST请求向我发送消息。我使用集成在Visual Studio中的选项“添加服务参考”生成了服务DTO。
这是一个自动生成的类的示例:
[Route("/test", "POST")]
[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "3.0.4506.2152")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true,
Namespace="http://www.reservationassistant.com/Booking/Types")]
public partial class UpdateBookingRequest
{
private Booking bookingField;
private string resortIdField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public Booking Booking
{
get
{
return this.bookingField;
}
set
{
this.bookingField = value;
}
}
当我创建ServiceInterface方法并运行服务时,进入元数据页面,我会收到以下示例SOAP消息
<UpdateBookingRequest>
<bookingField>
....
<bookingField>
<UpdateBookingRequest>
这是我的服务接口类中的代码:
UpdateBookingResponse Post(UpdateBookingRequest request)
{
// do stuff with request
return null;
}
您可能暗指自动生成的类,我收到的消息将具有与生成的DTO中的公共属性相同的标记名。但是,这将永远不可能,因为对于某些原因,ServiceStack试图将传入的XML消息元素绑定到DTO的私有字段(由我的服务的元数据页面生成的示例SOAP消息-请在“预订”后注意“ field”后缀”)。如何使传入消息绑定到公共属性而不是私有字段?
答案 0 :(得分:1)
首先,如果需要Type C#服务,我强烈建议在C# Add ServiceStack Reference中使用更具弹性,多功能,更清洁和更快的替代方法。 SOAP是slow, fragile and bloated serialization format,只应在旧式集成中考虑。
默认情况下,ServiceStack使用.NET XML DataContract Serializer进行XML或SOAP序列化,因此其行为取决于.NET的XML DataContractSerializer
实现。
对于处理SOAP,它使用WCF的通用Message
类,默认情况下使用DataContractSerializer
,但是您可以通过在您的目录上添加[XmlSerializerFormat] attribute来使用XmlSerializer实现切换为填充WCF的Message
请求和响应DTO。
您可以请求.NET的WCF svcutil使用/serializer
命令行开关来强制生成DataContract或XmlSerializer类,例如:
svcutil endpoint.wsdl /serializer:DataContractSerializer
svcutil endpoint.wsdl /serializer:XmlSerializer
您可以注册custom Content Type来覆盖用于XML请求的Xml序列化,例如您可以覆盖它以使用XmlSerializer
实现来处理XML请求,例如:
ContentTypes.Register(MimeTypes.Xml,
(req, dto, stream) => {
using (var xw = XmlWriter.Create(stream))
{
var ser = new XmlSerializerWrapper(dto.GetType());
ser.WriteObject(xw, dto);
}
},
(type, stream) => {
using (var reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas()))
{
var serializer = new System.Xml.Serialization.XmlSerializer(type);
return serializer.Deserialize(reader);
}
});
当您从元数据预览中推断行为时,请注意,预览不是使用WCF序列化器用于SOAP请求生成的,因此请求正文是使用DataContraceSerializer
生成的,因此,如果在WCF消息中使用XmlSerializer实现。