我使用本地WSDL为项目添加了SAP Netweaver服务引用。服务器返回一个空响应,但使用Fiddler我可以看到正在发送的响应。我认为这意味着响应没有被正确反序列化。这是在WSDL中定义根响应元素的方式:
<xsd:element name="adrl">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="adr" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
子元素(某些字段已被省略):
<xsd:element name="adr">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="id"/>
</xsd:sequence>
<xsd:attribute name="op" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="update"/>
<xsd:enumeration value="delete"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
响应:
<wsdl:output message="p1:p2.adrl"/>
命名空间:
xmlns:p1="urn:mycompany:outbound"
xmlns:p2="http://tempuri.org/mycompany"
来自服务的SOAP响应:
<SOAP:Envelope xmlns:SOAP='http://schemas.xmlsoap.org/soap/envelope/'>
<SOAP:Header/>
<SOAP:Body>
<adrl>
<adr op='update'>
<id>9AF1FBA0-81A4-4427-A011-0DCE3BD1F609</id>
</adr>
</adrl>
</SOAP:Body>
</SOAP:Envelope>
WCF类定义(来自Reference.cs):
// Some namespaces elided
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://tempuri.org/mycompany")]
public partial class adr : object, System.ComponentModel.INotifyPropertyChanged {
private string idField;
// adrOP has a suitable enumeration defined elsewhere in the file
private adrOP opField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public string id {
get {
return this.idField;
}
set {
this.idField = value;
this.RaisePropertyChanged("id");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public adrOP op {
get {
return this.opField;
}
set {
this.opField = value;
this.RaisePropertyChanged("op");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class GetAdrResponse {
[System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://tempuri.org/mycompany", Order=0)]
[System.Xml.Serialization.XmlArrayItemAttribute("adr", IsNullable=false)]
public adr[] adrl;
public GetAdrResponse() {
}
public GetAdrResponse(adr[] adrl) {
this.adrl = adrl;
}
}
当我尝试手动反序列化我在Fiddler中捕获的响应时(以adrl作为根元素),我得到了内部异常消息“”的Xml错误并不是预料到的。如果我add a root element到序列化程序,则错误消失,但只有“op”属性被正确反序列化。其余字段为空。
可能是什么问题?我实际上无法访问服务,但如果有必要更改的内容,我可以转发请求。否则我正在考虑添加MessageInspector并修改响应,但我不确定应该以哪种方式修改它。
编辑:我在C#中创建了对象并对其进行了反序列化,这就是结果:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfAdr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<adr op="update">
<id>9AF1FBA0-81A4-4427-A011-0DCE3BD1F609</id>
</adr>
</ArrayOfAdr>
似乎根元素在序列化方面没有正确定义。
答案 0 :(得分:1)
当我尝试在SAP Netweaver EJB DC中使用WCF服务时遇到了同样的问题。我通过将XmlSerializerFormat标记添加到WCF服务中的每个操作和XmlRoot标记到数据协定来解决了这个问题:
[XmlRoot(Namespace = "urn:sap.com:WS:Service1", ElementName = "Entity1")]
[DataContract]
public class Entity1
{
// your properties
}
[ServiceContract(Namespace = "urn:sap.com:WS:Service1", Name = "IService1")]
public interface IService1
{
[XmlSerializerFormat(Style = OperationFormatStyle.Document, Use = OperationFormatUse.Literal)]
[OperationContract]
Entity1 GetById(int id);
[XmlSerializerFormat(Style = OperationFormatStyle.Document, Use = OperationFormatUse.Literal)]
[OperationContract]
string Save(Entity1 entity);
}
[ServiceBehavior(Namespace = "urn:sap.com:WS:Service1", Name = "Service1")]
[BindingNamespaceBehavior(bindingNamespace = "urn:sap.com:WS:Service1")]
public class Service1 : IService1
{
Entity1 GetById(int id)
{
// your code
}
string Save(Entity1 entity)
{
// your code
}
}