ServiceStack试图绑定通过服务引用而不是公共属性生成的私有字段类



有一个远程服务,我正在尝试使用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消息-请注意"预订"之后的"字段"后缀(。如何使传入消息绑定到公共属性而不是私有字段?

首先,如果您想要Typed C#服务,我强烈建议您使用C#Add ServiceStack Reference中更具弹性、更通用、更干净、更快的替代方案。SOAP是一种缓慢、脆弱和臃肿的序列化格式,只应考虑用于遗留集成。

默认情况下,ServiceStack使用。NET XML DataContract序列化程序,用于XML或SOAP序列化,因此行为依赖于。NET的XMLDataContractSerializer实现。

为了处理SOAP,它使用WCF的通用Message类,默认情况下使用DataContractSerializer,但您可以通过在请求和响应DTO上添加[XmlSerializerFormat]属性,切换到使用XmlSerializer实现填充WCF的Message

你可以提出要求。NET的WCF svcutil使用/serializer命令行开关强制生成DataContract或XmlSerializer类,例如:

svcutil endpoint.wsdl /serializer:DataContractSerializer
svcutil endpoint.wsdl /serializer:XmlSerializer

覆盖内容类型

您可以注册自定义内容类型以覆盖用于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);
}                    
});

SOAP请求的元数据预览

当您从元数据预览中推断行为时,请注意,预览不是使用WCF Serializer for SOAP Request生成的,请求正文是使用DataContraceSerializer生成的,因此如果在WCF Message中使用XmlSerializer实现,它不会反映相同的输出。

最新更新