【发布时间】:2019-12-12 09:09:28
【问题描述】:
我正在编写一个库来使用第 3 方 Web 服务(我显然无法更改)。该库当前设置为 .Net Standard 2.0,以便我可以在我当前的应用程序(.Net Framework 4.6.2)和未来可能在 .Net Core 中开发的项目中使用它。这不是必需的,但如果可能的话,我想保持这种方式。
我使用 Microsoft WCF Web Service Reference Provider 实用程序从 WSDL 生成代理类。所以我的基本客户端工厂如下所示:
public static class AuthenticationClientFactory
{
public static AuthenticationClient CreateNew()
{
//Specify the binding to be used for the client.
BasicHttpsBinding binding = new BasicHttpsBinding();
//Specify the address to be used for the client.
EndpointAddress address = new EndpointAddress(Globals.WebServiceAuthenticationURL);
var client = new AuthenticationClient(binding, address);
return client;
}
}
在上面生成的 AuthenticationClient 上调用“AuthenticateAsync”方法时,请求创建如下:
<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:MessageId i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:h="http://centiro.com/facade/shared/1/0/datacontract" />
</s:Header>
<s:Body>
<AuthenticateRequest xmlns:d3p1="http://schemas.datacontract.org/2004/07/Centiro.Facade.Common.Operations.Authenticate" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://centiro.com/facade/shared/1/0/servicecontract">
<d3p1:Password>Pass123</d3p1:Password>
<d3p1:UserName>User123</d3p1:UserName>
</AuthenticateRequest>
</s:Body>
</s:Envelope>
使用 SoapUI,我针对服务测试了 XML,我收到了“HTTP/1.1 400 Bad Request”。起初,我从肥皂消息中剥离了所有内容,最后将问题缩小到 XML 声明。完全剥离 XML 声明,或将声明更改为 "" 允许服务成功处理请求。
所以问题是,我如何完全剥离 XML 声明,或者更好地将声明改为“utf-8”(我通过 SoapUI 确认有效)?
我已经尝试过的事情:
- 将 BasicHttpsBinding 上的 TextEncoding 显式更改为 utf-8。 XML 声明仍然是 utf-16。
- 使用明确设置为 Soap11 和 utf-8 编码的 TextMessageEncodingBindingElement 创建 CustomBinding。
- 使用 MessageInspector 使用 utf-8 重新编码消息。 (但这最终只会重新编码消息的正文)
这似乎应该是一个如此简单的改变。此时,我已准备好通过 WebClient 对象构建自己的客户端,以便更好地控制,我将自己构建对象和序列化。我在多个地方读到过,WCF 默认情况下会自动将所有内容编码为 utf-8,所以我不确定为什么声明以“utf-16”开头。
【问题讨论】:
-
我发现这样做的唯一方法是解析像 Yitzhak 解决方案这样的字符串。解析必须至少包含 ident 行和根标记。
-
有
Authenticate和AuthenticateAsync吗?如果是这样,如果你改为调用它会发生什么? -
@dbc 不幸的是,Authenticate 和 AuthenticateAsync 方法都产生完全相同的 Soap 消息。