gpt4 book ai didi

c# - 同时包含 "application/xml"和 "text/xml"ContentTypes 的 WCF 绑定(bind) SOAP 1.1 请求

转载 作者:太空宇宙 更新时间:2023-11-03 10:29:47 27 4
gpt4 key购买 nike

我正在尝试用新的 WCF 服务替换遗留的 SOAP 1.1 网络服务。

已有的客户端很多,改变它们是不可行的。

我已经成功创建了一项服务,它适用于大多数客户端,但有一个令人恼火的异常。

由于旧服务是 SOAP 1.1,我尝试使用 basicHttpBinding,例如:

<bindings>
<basicHttpBinding>
<binding name="Whatever" />
</basicHttpBinding>
</bindings>

我的大部分入站消息都像下面的例子,一切正常:

POST http://MySoapWebServiceUrl/Service.svc HTTP/1.1
SOAPAction: DoSomething
Content-Type: text/xml;charset=UTF-8
Content-Length: 1234
Host: MySoapWebServiceUrl

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<xml:InputStuffHere />
</soap:Body>
</soap:Envelope>

我的问题是几个调用者发送完全相同的消息,除了 header 中的 Content-Type 为“application/xml”,并收到此错误:

Error: 415 Cannot process the message because the content type 'application/xml' was not the expected type 'text/xml'.

我已经尝试切换到使用 wsHttpBindingwebHttpBinding 进行绑定(bind)。

但是,我无法在这些绑定(bind)中找到允许“application/xml”和“text/xml”的内容类型以及 header 中的 SOAP 1.1 样式“SOAPAction”寻址的设置组合。

我还尝试实现自定义文本消息编码器,从 Microsoft 的 WCF 示例 CustomTextMessageEncodingElement 开始。

但是,使用自定义文本消息编码器,我可以将 MediaType 设置为“application/xml”或“text/xml”。但是,毫不奇怪,发送指定 Content-Type 的客户端成功,但使用其他 Content-Type 的客户端失败。

我还尝试设置 MediaType,包括像 '*/xml' 这样的通配符,但这对所有调用者来说都失败了。

有没有一种方法可以创建 WCF 绑定(bind),以便服务可以接受“application/xml”或“text/xml”的内容类型?

最佳答案

我相信我试图做的事情根本不可能。

我得出的结论是,WCF 是一种不适合实现向后兼容的替代遗留 SOAP Web 服务的技术,后者允许在 header 中使用各种 Content-Type 值。

相反,我使用 System.Web.IHttpModule 实现了自定义 HttpModule。

下面是基本的实现细节,适用于发现自己陷入这个兔子洞并需要出路的任何其他人。

代码:

public class MyCustomHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += OnBegin;
}

private void OnBegin(object sender, EventArgs e)
{
var app = (HttpApplication) sender;
var context = app.Context;

if (context.Request.HttpMethod == "POST")
{
string soapActionHeader = context.Request.Headers["SOAPAction"];
byte[] buffer = new byte[context.Request.InputStream.Length];
context.Request.InputStream.Read(buffer, 0, buffer.Length);
context.Request.InputStream.Position = 0;

string rawRequest = Encoding.ASCII.GetString(buffer);

var soapEnvelope = new XmlDocument();
soapEnvelope.LoadXml(rawRequest);

string response = DoSomeMagic(soapActionHeader, soapEnvelope);

context.Response.ContentType = "text/xml";
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.Write(response);
}
else
{
//do something else
//returning a WSDL file for an appropriate GET request is nice
}

context.Response.Flush();
context.Response.SuppressContent = true;
context.ApplicationInstance.CompleteRequest();
}

private string DoSomeMagic(string soapActionHeader, XmlDocument soapEnvelope)
{
//magic happens here
}

public void Dispose()
{
//nothing happens here
//a Dispose() implementation is required by the IHttpModule interface
}
}

网络配置:

<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="MyCustomHttpModule" type="AppropriateNamespace.MyCustomHttpModule"/>
</modules>
</system.webServer>

关于c# - 同时包含 "application/xml"和 "text/xml"ContentTypes 的 WCF 绑定(bind) SOAP 1.1 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30634279/

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