0


【C#】标准WebService Soap1.1 兼容 ContentType: application/xml

一、问题描述

1.1 ESB平台要求

  • ContentTypeapplication/xml
  • Soap协议版本1.1

1.2 提供的 WebService 接口

  • 语言:C#
  • 目标框架.NetFramework 4.6.1

1.3 Postman 测试结果

HTTP Error 415.0 - Unsupported Media Type

服务器无法为请求提供服务,因为不支持该媒体类型。
最可能的原因:
所请求文件的格式已由服务器配置为不可进行下载。

可尝试的操作:
确认所请求文件的格式有效。

Detailed Error Information:
ModuleManagedPipelineHandlerRequested URLhttp://localhost:55305/WebService.asmx?op=callBussinessNotificationExecuteRequestHandlerPhysical Path…\ESBWebService.asmxHandlerWebServiceHandlerFactory-Integrated-4.0Logon Method匿名Error Code0x00000000Logon User匿名
More Information:
如果服务器因不支持该文件类型而无法为请求提供服务,就会出现此错误。
View more information »

二、问题说明

C# 使用创建的标准WebService 只支持以下ContentType类型

  • SOAP 1.1text/xml; charset=utf-8
  • SOAP 1.2application/soap+xml; charset=utf-8
  • HTTP POSTapplication/x-www-form-urlencoded

综上所述,要想解决此问题,由以下两种途径:

  • ESB平台人员沟通,要求使用WebService所支持的媒体类型text/xml;
  • 自己扩展SOAP,拦截application/xml类型的请求

三、解决方案

3.1 与ESB平台人员沟通,要求使用WebService所支持的媒体类型

text/xml;

在这里插入图片描述

3.2 自己扩展SOAP,拦截

application/xml

类型的请求

要在

C#
WebService

启动服务时支持

application/xml

文件类型,您可以通过在

WebService

服务代码中添加一个

SOAP

扩展来实现。

3.2.1 扩展 SoapExtensionAttribute

[AttributeUsage(AttributeTargets.Method)]publicclassESBSoapExtensionAttribute:SoapExtensionAttribute{privateint priority;publicESBSoapExtensionAttribute(){}publicoverrideType ExtensionType
    {get{returntypeof(ESBSoapExtension);}}publicoverrideint Priority
    {get{return priority;}set{ priority =value;}}}

3.2.2 扩展 SoapExtension

ProcessMessage

中判断

ContentType

是不是

"application/xml"

,如果是则替换为可以被解析的

"text/xml"
publicclassESBSoapExtension:SoapExtension{publicESBSoapExtension extension;publicoverrideobjectGetInitializer(LogicalMethodInfo methodInfo,SoapExtensionAttribute attribute){return extension ??(extension =newESBSoapExtension());}publicoverrideobjectGetInitializer(Type serviceType){return extension ??(extension =newESBSoapExtension());}publicoverridevoidInitialize(object initializer){//base.Initialize(initializer);}publicoverridevoidProcessMessage(SoapMessage message){// 检查请求头Content-Type是否为"application/xml"try{switch(message.Stage){case SoapMessageStage.BeforeDeserialize:if(message isSoapServerMessage serverMessage && serverMessage.ContentType.Contains("application/xml")){// 设置响应头Content-Type为"application/xml"
                        serverMessage.ContentType ="text/xml";}break;case SoapMessageStage.BeforeSerialize:break;case SoapMessageStage.AfterSerialize:break;case SoapMessageStage.AfterDeserialize:// 在反序列化之后进行处理(响应阶段)break;default:break;}}catch(Exception exp){}}}

3.2.3 在方法

callBussiness

上注入扩展

[WebMethod(Description ="调用业务")][ESBSoapExtension(Priority =1)]publicstringcallBussiness(string message){return message;}

** 完整代码**

usingSystem;usingSystem.IO;usingSystem.Text;usingSystem.Web;usingSystem.Web.Script.Serialization;usingSystem.Web.Services;usingSystem.Web.Services.Protocols;usingSystem.Xml;usingSystem.Xml.Serialization;usingRss_WebServer.code;[AttributeUsage(AttributeTargets.Method)]publicclassESBSoapExtensionAttribute:SoapExtensionAttribute{privateint priority;publicESBSoapExtensionAttribute(){}publicoverrideType ExtensionType
    {get{returntypeof(ESBSoapExtension);}}publicoverrideint Priority
    {get{return priority;}set{ priority =value;}}}publicclassESBSoapExtension:SoapExtension{publicESBSoapExtension extension;publicoverrideobjectGetInitializer(LogicalMethodInfo methodInfo,SoapExtensionAttribute attribute){return extension ??(extension =newESBSoapExtension());}publicoverrideobjectGetInitializer(Type serviceType){return extension ??(extension =newESBSoapExtension());}publicoverridevoidInitialize(object initializer){//base.Initialize(initializer);}publicoverridevoidProcessMessage(SoapMessage message){// 检查请求头Content-Type是否为"application/xml"try{switch(message.Stage){case SoapMessageStage.BeforeDeserialize:if(message isSoapServerMessage serverMessage && serverMessage.ContentType.Contains("application/xml")){// 设置响应头Content-Type为"application/xml"
                        serverMessage.ContentType ="text/xml";}break;case SoapMessageStage.BeforeSerialize:break;case SoapMessageStage.AfterSerialize:break;case SoapMessageStage.AfterDeserialize:// 在反序列化之后进行处理(响应阶段)break;default:break;}}catch(Exception exp){}}}namespaceESB{/// <summary>/// WebService 的摘要说明/// </summary>[WebService(Namespace ="http://esb.webservice")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)]// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 [System.Web.Script.Services.ScriptService]publicclassWebService:System.Web.Services.WebService{publicoverrideobjectGetService(Type service){returnbase.GetService(service);}publicWebService(){//this.Application.sathis.Context.Request.ContentType ="application/xml";}[WebMethod(Description ="调用业务")][ESBSoapExtension(Priority =1)]publicstringcallBussiness(string message){try{if(string.IsNullOrEmpty(message)){
                    message =WebServiceAnalysis(base.Context.Request,nameof(message));}return message;}catch(Exception exp){return exp.Message;}}/// <summary>/// 重新解析 WebService/// </summary>/// <param name="request"></param>/// <param name="name"></param>/// <returns></returns>privatestringWebServiceAnalysis(System.Web.HttpRequest request,string name){try{if(request.ContentLength ==0){thrownewException($"Body(xml数据) 无数据");}// 获取请求内容Stream inputStream = request.InputStream;// 重新获取内容
                inputStream.Position =0;// 读取请求主体内容using(StreamReader reader =newStreamReader(inputStream, Encoding.UTF8)){string requestBody = reader.ReadToEnd();XmlDocument xmlDoc =newXmlDocument();
                    xmlDoc.LoadXml(requestBody);XmlNode strNode = xmlDoc.SelectSingleNode($"//{name}");if(strNode !=null){return strNode.InnerText;}else{thrownewException($"未在Body(xml数据)找到{name}节点");}}}catch(Exception exp){throw exp;}}}}
标签: c# Soap ContentType

本文转载自: https://blog.csdn.net/chenlu5201314/article/details/133708578
版权归原作者 少莫千华 所有, 如有侵权,请联系我们删除。

“【C#】标准WebService Soap1.1 兼容 ContentType: application/xml”的评论:

还没有评论