我正在尝试将Java Web服务集成到我的C#项目中。网络服务由我公司的另一个部门维护,不受我的控制。
我已经创建了一个服务引用,我可以调用该服务。问题是所有响应对象的属性都为null。 SOAP响应从服务器返回,但没有正确反序列化。报告或记录没有错误。
这似乎是一个相当普遍的问题,常见的答案是命名空间不匹配。我相信这也是我的问题,但我无法纠正它。
网络服务是私密的。我试图整理一个说明问题的样本。这是相关的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)) {
{
o.@CallSuccessful = 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,请告诉我,我会看到我能做什么。
答案 0 :(得分:1)
WSDL很可能没有具有正确名称空间的CallSuccessful和CallErrorMessage标记,这就是您的服务代理类没有相应名称空间的原因。
您实际上可以下载WSDL,将其保存在项目中,根据需要处理命名空间,从此WSDL生成服务引用(通过使用GUI向导或svcutil),指向app.config或web。配置文件到实际的java Web服务。每次需要更新服务时,您都可以按照此过程进行操作。
希望这有帮助。