在调用 SOAP WS 时,我们必须在 SOAP 标头中指定 wsa。它看起来像这样:
<env:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:To env:mustUnderstand="true">_enpoint_</wsa:To>
<wsa:Action>_action_</wsa:Action>
</env:Header>
我们已经使用 wsdl.exe 从 wsdl 自动生成代理
为了避免修改自动生成的代码,我想添加一个新的部分类来完成这项工作。我喜欢这种方法,所以我最终得到了这段代码:
public partial class WebserviceProxy
{
private const string DEFAULT_WSA_NAMESPACE = "wsa";
private string _wsaNamespace;
public string WsaNamespace
{
get => _wsaNamespace ?? (_wsaNamespace = DEFAULT_WSA_NAMESPACE);
set => _wsaNamespace = value;
}
public string To { get; set; }
public string Action { get; set; }
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest request = base.GetWebRequest(uri);
request.Headers.Add($"{WsaNamespace}:{nameof(To)}", To);
request.Headers.Add($"{WsaNamespace}:{nameof(Action)}", Action);
return request;
}
}
问题是此代码不起作用,并且在调用时出现异常base.GetWebRequest(uri)
:
System.ArgumentException: Specified value has invalid HTTP Header characters.
Parameter name: name
at System.Net.WebHeaderCollection.CheckBadChars(String name, Boolean isHeaderValue)
at System.Net.WebHeaderCollection.Add(String name, String value)
at IcamWebserviceProxy.GetWebRequest(Uri uri)
由于我不确定我是否走在正确的轨道上,所以我在这里寻求帮助。
即使解决了上述问题,我仍然必须将正确的 wsa 命名空间指定为 Heder 属性。
[编辑] URI(针对在同一台机器上运行的 SoapUI 端点进行测试):
- uri {http://localhost:9000/mockDataExchangeAdminservice} System.Uri
AbsolutePath "/mockDataExchangeAdminservice" string
AbsoluteUri "http://localhost:9000/mockDataExchangeAdminservice" string
AllowIdn false bool
Authority "localhost:9000" string
DnsSafeHost "localhost" string
Fragment "" string
HasAuthority true bool
Host "localhost" string
HostNameType Dns System.UriHostNameType
HostType DnsHostType System.Uri.Flags
IdnHost "localhost" string
IsAbsoluteUri true bool
IsDefaultPort false bool
IsDosPath false bool
IsFile false bool
IsImplicitFile false bool
IsLoopback true bool
IsNotAbsoluteUri false bool
IsUnc false bool
IsUncOrDosPath false bool
IsUncPath false bool
LocalPath "/mockDataExchangeAdminservice" string
OriginalString "http://localhost:9000/mockDataExchangeAdminservice" string
OriginalStringSwitched false bool
PathAndQuery "/mockDataExchangeAdminservice" string
Port 9000 int
PrivateAbsolutePath "/mockDataExchangeAdminservice" string
Query "" string
Scheme "http" string
SecuredPathIndex 0 ushort
+ Segments {string[2]} string[]
+ Syntax {System.UriParser.BuiltInUriParser} System.UriParser {System.UriParser.BuiltInUriParser}
UserDrivenParsing false bool
UserEscaped false bool
UserInfo "" string
m_DnsSafeHost null string
m_Flags DnsHostType | AuthorityFound | LoopbackHost | NotDefaultPort | MinimalUriInfoSet | AllUriInfoSet | HostUnicodeNormalized | RestUnicodeNormalized System.Uri.Flags
+ m_Info {System.Uri.UriInfo} System.Uri.UriInfo
m_String "http://localhost:9000/mockDataExchangeAdminservice" string
+ m_Syntax {System.UriParser.BuiltInUriParser} System.UriParser {System.UriParser.BuiltInUriParser}
m_iriParsing true bool
m_originalUnicodeString null string
+ Static members
HttpWebClientProtocol.GetWebRequest
[edit2]返回 webRequest 时抛出异常(最后一行):
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest webRequest = base.GetWebRequest(uri);
HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
if (httpWebRequest != null)
{
httpWebRequest.UserAgent = this.UserAgent;
httpWebRequest.AllowAutoRedirect = this.allowAutoRedirect;
httpWebRequest.AutomaticDecompression = this.enableDecompression ? DecompressionMethods.GZip : DecompressionMethods.None;
httpWebRequest.AllowWriteStreamBuffering = true;
httpWebRequest.SendChunked = false;
if (this.unsafeAuthenticatedConnectionSharing != httpWebRequest.UnsafeAuthenticatedConnectionSharing)
httpWebRequest.UnsafeAuthenticatedConnectionSharing = this.unsafeAuthenticatedConnectionSharing;
if (this.proxy != null)
httpWebRequest.Proxy = this.proxy;
if (this.clientCertificates != null && this.clientCertificates.Count > 0)
httpWebRequest.ClientCertificates.AddRange(this.clientCertificates);
httpWebRequest.CookieContainer = this.cookieJar;
}
return webRequest;
}