WCF客户端/ Java Web服务 - 反序列化对象为空
我正在尝试将Java Web服务集成到我的C#项目中。 Web服务由我公司的另一个部门维护,并且不受我的控制。WCF客户端/ Java Web服务 - 反序列化对象为空
我已经创建了一个服务引用,我可以调用该服务。问题是所有的响应对象的属性都是空的。 SOAP响应从服务器返回,但它没有得到正确的反序列化。没有错误报告或记录。
这似乎是一个相当普遍的问题,常见的答案是有一个名称空间不匹配。我相信这也是我的问题,但我很难纠正它。
该Web服务是私人的。我试图把说明问题的一个样本放在一起。下面是相关Reference.cs代码:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace = "www.namespace1.com", ConfigurationName = "MyService.MyServiceClient")]
public interface MyServiceClient
{
[System.ServiceModel.OperationContractAttribute(Action = "", ReplyAction = "*")]
[System.ServiceModel.XmlSerializerFormatAttribute(Style = System.ServiceModel.OperationFormatStyle.Rpc, SupportFaults = true, Use = System.ServiceModel.OperationFormatUse.Encoded)]
[System.ServiceModel.ServiceKnownTypeAttribute(typeof(MyOperationResponseType))]
myOperationResponse myOperation(myOperationRequest request);
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.SoapTypeAttribute(Namespace = "www.namespace2.com")]
public partial class MyOperationResponseType : object, System.ComponentModel.INotifyPropertyChanged
{
private bool callSuccessfulField;
private string callErrorMessageField;
/// <remarks/>
public bool CallSuccessful
{
get
{
return this.callSuccessfulField;
}
set
{
this.callSuccessfulField = value;
this.RaisePropertyChanged("CallSuccessful");
}
}
/// <remarks/>
[System.Xml.Serialization.SoapElementAttribute(IsNullable = true)]
public string CallErrorMessage
{
get
{
return this.callErrorMessageField;
}
set
{
this.callErrorMessageField = value;
this.RaisePropertyChanged("CallErrorMessage");
}
}
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.ServiceModel.MessageContractAttribute(WrapperName = "myOperationResponse", WrapperNamespace="www.namespace1.com", IsWrapped = true)]
public partial class myOperationResponse
{
[System.ServiceModel.MessageBodyMemberAttribute(Namespace = "", Order = 0)]
public MyOperationResponseType result;
public myOperationResponse()
{
}
public myOperationResponse(MyOperationResponseType result)
{
this.result = result;
}
}
SOAP响应说我得到这个样子的:
<env:Envelope env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<m:myOperationResponse xmlns:m="www.namespace1.com">
<result>
<ns2:CallSuccessful xmlns:ns2="www.namespace2.com">false</ns2:CallSuccessful>
<ns2:CallErrorMessage xmlns:ns2="www.namespace2.com">Failed for some reason.</ns2:CallErrorMessage>
</result>
</m:myOperationResponse>
</env:Body>
</env:Envelope>
MyOperationResponseType的实例被创建,但CallErrorMessage和CallSuccessful字段不填充。
我用SGEN生成XML序列化类,发现它是一个命名空间问题。下面的代码节选自deserialzer:
string id2_Item;
id2_Item = Reader.NameTable.Add(@"");
global::MyOperationResponseType o;
o = new global::MyOperationResponseType();
if (!paramsRead[1] && ((object) Reader.LocalName == (object)id158_CallSuccessful && (object) Reader.NamespaceURI == (object)id2_Item)) {
{
[email protected] = System.Xml.XmlConvert.ToBoolean(Reader.ReadElementString());
}
paramsRead[1] = true;
}
有条件的失败,因为Reader.NamespaceURI = "www.namespace2.com"
和id2_Item = ""
如果我手动设置id2_Item = "www.namespace2.com"
然后反序列化的作品。
另外,如果我脱光了命名空间出来的响应SOAP的,它会工作:
<env:Envelope env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<m:myOperationResponse xmlns:m="www.namespace1.com">
<result>
<CallSuccessful>false</CallSuccessful>
<CallErrorMessage>Failed for some reason.</CallErrorMessage>
</result>
</m:myOperationResponse>
</env:Body>
我有解决方法:
- 创建和维护一个自定义序列。
- 在反序列化之前从响应中剥离命名空间。
但是,我想找到一种方法来使这项工作没有解决方法。我似乎无法找到一种让命名空间匹配的方法。我尝试了各种不同的属性,但似乎没有什么区别。
我还没有发布WSDL。这是一项私人服务,我无法对其进行任何更改。如果您需要查看WSDL,请告诉我,我会看看我能做些什么。
最有可能的WSDL没有CallSuccessful和CallErrorMessage标签的正确名称空间,这就是为什么您的服务代理类没有适当的名称空间。
实际上,您可以下载WSDL,将其保存在项目中,处理需要的名称空间,通过此WSDL生成服务引用(通过使用GUI向导或svcutil),指向app.config或web .config文件到实际的java web服务。每次需要更新服务时,您都可以按照此过程进行操作。
希望这会有所帮助。
这是为什么用Java标记的? – Perception
@Perception:Web服务是一个Java Web服务。这种互操作性问题似乎相当普遍,所以我认为一些Java开发人员可能会提供一些见解。这是我的第一个问题,所以也许我对标签有点过分了。 –
我发现与rpc /编码服务和复杂类型命名空间的根本问题。我在这里问了一个更详细的问题:[link](http://stackoverflow.com/questions/7840665/wcf-client-soap-encoding-complex-types-in-different-namespace) –