Добавление заголовков wsa в вызов SOAP
При вызове SOAP WS мы должны указать wsa в заголовке SOAP. Это будет выглядеть так:
<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, используя wsdl.exe
Чтобы избежать необходимости изменения автоматически сгенерированного кода, я хотел добавить новый частичный класс, выполняющий эту работу. Мне нравится этот подход, поэтому я получил следующий код:
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.
[edit] 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
[edit2] Исключение выдается из HttpWebClientProtocol.GetWebRequest
при возврате 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;
}