gpt4 book ai didi

c# - 强制使用 mustunderstand = 1 的 SOAP header ,即使调用 beforesendrequest 方法也是如此

转载 作者:行者123 更新时间:2023-11-30 22:57:30 30 4
gpt4 key购买 nike

我从 NVMS 下载了一个 C# 实现示例,以了解如何实现他们的 Web 服务。它使用 SOAP 请求来调用不同的服务。在源代码中,有一个实现 IEndpointBehavior 和 IClientMessageInspector 的内部类,在 BeforeSendRequest 中他们清除了 SOAP header ,但从我得到的响应来看,最终请求仍然有 header 。我尝试了在 SOAPUI 的控制台中打印的两个请求(有和没有 header )并且无 header 请求有效,而另一个给我的消息与我在 C# 应用程序本身中得到的消息相同。

这是类(class):

internal class CustomMessageInspector : IEndpointBehavior, IClientMessageInspector
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(this);
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}

public void Validate(ServiceEndpoint endpoint)
{
}

/*public void BeforeSendReply(ref Message reply, object correlationState)
{
reply.Headers.Clear();
}*/

//add using directive Message = System.ServiceModel.Channels.Message;
public void AfterReceiveReply(ref Message reply, object correlationState)
{
// WORKAROUND for WCF-Exception "The MessageHeader is already understood"
// (Note: The message still gets validated)
reply.Headers.Clear();
Console.WriteLine("received Response:");
Console.WriteLine("{0}\r\n", reply);
}

/// <summary>
/// Shows the sent message with and without SOAP-Header
/// </summary>
/// <param name="request"></param>
/// <param name="channel"></param>
/// <returns></returns>
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
// Fait la même chose que le clear, mais ne fonctione pas non plus...
/*request.Headers.ReplyTo = null;
request.Headers.Action = null;
request.Headers.MessageId = null;*/
Console.WriteLine("original Request:");
Console.WriteLine("{0}\r\n", request);
// Ne semble pas fonctionner, la requête est envoyée avec les headers...
request.Headers.Clear();

Console.WriteLine("without Header Request:");
Console.WriteLine("{0}\r\n", request);

return null;
}
}

“request.Headers.Clear();”线应该在这里工作。请求参数通过引用传递,因此它应该清除源对象中的 header 。但这是我得到的结果:

received Response:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<s:Header xmlns:s="http://www.w3.org/2003/05/soap-envelope" />
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:MustUnderstand</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">MustUnderstand headers: [{http://www.w3.org/2005/08/addressing}To] are not understood.</soap:Text>
</soap:Reason>
</soap:Fault>
</soap:Body>
</soap:Envelope>

这是 2 个请求(带和不带 header ,由 beforesendrequest 方法打印):

original Request:
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">ns:G110RequestMessage</a:Action>
<a:MessageID>urn:uuid:405c0e93-f39d-4d8b-bef8-72cf82f88203</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<G110Request xmlns="urn:wsdltypes.nmvs.eu:v3.0">
<Header xmlns="urn:types.nmvs.eu:v3.0">
<Auth>
<ClientLoginId>ABC</ClientLoginId>
<UserId>test123</UserId>
<Password>123456</Password>
</Auth>
<UserSoftware d5p1:name="Test Soft" d5p1:supplier="Comp Any" d5p1:version="V2" xmlns:d5p1="urn:types.nmvs.eu:v3.0" />
<Transaction>
<ClientTrxId>7775559966aaa</ClientTrxId>
<Language>eng</Language>
</Transaction>
</Header>
<Body xmlns="urn:types.nmvs.eu:v3.0">
<Product>
<ProductCode d6p1:scheme="GTIN" xmlns:d6p1="urn:types.nmvs.eu:v3.0">PK001C854A8EE536949</ProductCode>
<Batch>
<Id>TESTA1596337CF</Id>
<ExpDate>231130</ExpDate>
</Batch>
</Product>
<Pack d5p1:sn="PK001C854A8EE536949" xmlns:d5p1="urn:types.nmvs.eu:v3.0" />
</Body>
</G110Request>
</s:Body>
</s:Envelope>

without Header Request:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header />
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<G110Request xmlns="urn:wsdltypes.nmvs.eu:v3.0">
<Header xmlns="urn:types.nmvs.eu:v3.0">
<Auth>
<ClientLoginId>ABC</ClientLoginId>
<UserId>test123</UserId>
<Password>123456</Password>
</Auth>
<UserSoftware d5p1:name="Test Soft" d5p1:supplier="Comp Any" d5p1:version="V2" xmlns:d5p1="urn:types.nmvs.eu:v3.0" />
<Transaction>
<ClientTrxId>7775559966aaa</ClientTrxId>
<Language>eng</Language>
</Transaction>
</Header>
<Body xmlns="urn:types.nmvs.eu:v3.0">
<Product>
<ProductCode d6p1:scheme="GTIN" xmlns:d6p1="urn:types.nmvs.eu:v3.0">PK001C854A8EE536949</ProductCode>
<Batch>
<Id>TESTA1596337CF</Id>
<ExpDate>231130</ExpDate>
</Batch>
</Product>
<Pack d5p1:sn="PK001C854A8EE536949" xmlns:d5p1="urn:types.nmvs.eu:v3.0" />
</Body>
</G110Request>
</s:Body>
</s:Envelope>

我试图更改 mustUnderstand 属性,但找不到更改位置。

最佳答案

好吧,经过一天多的搜索,我找到了解决方案。事实上,Nicolas Giannone 在这里提供了所有必要的代码 WSHttpBinding in .NetStandard or .NET core下面是来自 NMVS 的 C# 示例的 SinglePackPing 函数,经过修改以与沙箱和 V3 API 一起使用。

public static Boolean SinglePackPing( MyConfig myConfig, String pingString )
{
Boolean ok = false;

string endPoint = myConfig.SinglePackServicesEndPoint;

//Defines a secure binding with certificate authentication
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

// create a new binding based on the existing binding
var customTransportSecurityBinding = new CustomBinding( binding );
// locate the TextMessageEncodingBindingElement - that's the party guilty of the inclusion of the "To"
var ele = customTransportSecurityBinding.Elements.FirstOrDefault( x=>x is TextMessageEncodingBindingElement );
if( ele != null )
{
// and replace it with a version with no addressing
// replace {Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)}
// with {Soap12 (http://www.w3.org/2003/05/soap-envelope) AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)}
int index = customTransportSecurityBinding.Elements.IndexOf( ele );
var textBindingElement = new TextMessageEncodingBindingElement
{
MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None)
};
customTransportSecurityBinding.Elements[index] = textBindingElement;
}

//Creates ServiceClient, attach transport-binding, Endpoint and the loaded certificate
using( SinglePackServicesClient service = new SinglePackServicesClient( customTransportSecurityBinding, new EndpointAddress( endPoint ) ) )
{
using( X509Certificate2 cert = new X509Certificate2( myConfig.CertificateFilePath, myConfig.PrivateKeyPassword, X509KeyStorageFlags.PersistKeySet ) )
{

//Creates ServiceClient, attach transport-binding, Endpoint and the loaded certificate
service.ClientCredentials.ClientCertificate.Certificate = cert;
service.Endpoint.EndpointBehaviors.Add( new CustomMessageInspector() );
var bindingTest = service.Endpoint.Binding;

//Creates PingRequest and set the ping Input
SinglePackPingRequest ping = new SinglePackPingRequest();
ping.Input = pingString;

//Creates PingResponse, result of the request. Displays the response
SinglePackPingResponse pingResponse = service.PingSinglePack(ping);

ok = pingResponse.Output == pingString;

//Displays the response. If the request is successful, the output is equal to the input
Console.WriteLine( pingResponse.Output );
}
}

return ok;
}

希望对你有帮助。让我知道你的进展情况。

关于c# - 强制使用 mustunderstand = 1 的 SOAP header ,即使调用 beforesendrequest 方法也是如此,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53605807/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com