Visual Studio添加WSDL服务引用后调用方法报'soap:Server'未绑定前缀错误
问题解决:Unbound prefix used in qualified name 'soap:Server'
这个错误本质是服务端返回的SOAP响应不规范:响应里用了soap:前缀,但没在XML根节点声明对应的命名空间。你的客户端(大概率是.NET自动生成的服务引用客户端)对XML格式校验严格,所以触发报错;而SoapUI自带的解析器兼容性更强,能忽略这种小问题,所以调用正常。
下面给你几个可行的解决办法:
1. 让服务端修复响应(最稳妥)
直接找提供WSDL的服务方,让他们在SOAP响应的根元素里补上soap命名空间声明,标准格式如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <!-- 服务端返回的具体响应内容 --> </soap:Envelope>
补完之后,你的客户端就能正常解析响应了。
2. 客户端加消息拦截器(改不了服务端时用)
如果服务端没法调整,你可以在自己的客户端代码里加一个消息拦截器,在解析响应前自动补全缺失的命名空间:
第一步:编写拦截器类
public class SoapNamespaceFixer : IClientMessageInspector { // 发送请求前无需处理,直接返回null public object BeforeSendRequest(ref Message request, IClientChannel channel) { return null; } // 收到响应后补全命名空间 public void AfterReceiveReply(ref Message reply, object correlationState) { // 将响应转换为字符串进行处理 var buffer = reply.CreateBufferedCopy(int.MaxValue); var tempMsg = buffer.CreateMessage(); var reader = tempMsg.GetReaderAtBodyContents(); var responseXml = reader.ReadOuterXml(); // 检查是否缺少soap命名空间,无则补全 if (!responseXml.Contains("xmlns:soap=")) { var fixedXml = responseXml.Replace("<soap:", "<soap: xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\""); // 重新构建合法的SOAP消息 var newReply = Message.CreateMessage(reply.Version, reply.Headers.Action, XmlReader.Create(new StringReader(fixedXml))); newReply.Headers.CopyHeadersFrom(reply.Headers); newReply.Properties.CopyProperties(reply.Properties); reply = newReply; } buffer.Close(); } }
第二步:编写行为类绑定拦截器
public class SoapNamespaceFixerBehavior : IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { // 将拦截器添加到客户端运行时 clientRuntime.MessageInspectors.Add(new SoapNamespaceFixer()); } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } public void Validate(ServiceEndpoint endpoint) { } }
第三步:修改客户端调用代码
wsdlClient client = new wsdlClient(); // 给客户端添加命名空间修复行为 client.Endpoint.Behaviors.Add(new SoapNamespaceFixerBehavior()); type[] result = client.getResult(); // 现在可正常调用
3. 重新生成服务引用时调整配置
删掉现有的服务引用,重新添加时点击「高级」按钮:
- 尝试取消勾选「重用引用程序集中的类型」
- 将「XML序列化程序」改为
XmlSerializer(默认是DataContractSerializer)
部分不规范的WSDL用XmlSerializer生成的客户端兼容性更好,可能直接解决问题。
内容的提问来源于stack exchange,提问作者Akhtubir
相关产品推荐
相关产品推荐

