【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=callBussiness
NotificationExecuteRequestHandlerPhysical Path…\ESBWebService.asmx
HandlerWebServiceHandlerFactory-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)]
public class ESBSoapExtensionAttribute : SoapExtensionAttribute
{
    private int priority;
    public ESBSoapExtensionAttribute()
    {

    }
    public override Type ExtensionType
    {
        get { return typeof(ESBSoapExtension); }
    }

    public override int Priority
    {
        get { return priority; }
        set { priority = value; }
    }
}

3.2.2 扩展 SoapExtension

ProcessMessage中判断ContentType是不是"application/xml",如果是则替换为可以被解析的"text/xml"

public class ESBSoapExtension : SoapExtension
{
    public ESBSoapExtension extension;
    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return extension ?? (extension = new ESBSoapExtension());
    }

    public override object GetInitializer(Type serviceType)
    {
        return extension ?? (extension = new ESBSoapExtension());
    }

    public override void Initialize(object initializer)
    {
        //base.Initialize(initializer);
    }

    public override void ProcessMessage(SoapMessage message)
    {
        // 检查请求头Content-Type是否为"application/xml"
        try
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeDeserialize:
                    if (message is SoapServerMessage 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)]
 public string callBussiness(string message)
 {
	return message;
 }

** 完整代码**

using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using System.Xml.Serialization;
using Rss_WebServer.code;

[AttributeUsage(AttributeTargets.Method)]
public class ESBSoapExtensionAttribute : SoapExtensionAttribute
{
    private int priority;
    public ESBSoapExtensionAttribute()
    {

    }
    public override Type ExtensionType
    {
        get { return typeof(ESBSoapExtension); }
    }

    public override int Priority
    {
        get { return priority; }
        set { priority = value; }
    }

    
}

public class ESBSoapExtension : SoapExtension
{
    public ESBSoapExtension extension;
    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return extension ?? (extension = new ESBSoapExtension());
    }

    public override object GetInitializer(Type serviceType)
    {
        return extension ?? (extension = new ESBSoapExtension());
    }

    public override void Initialize(object initializer)
    {
        //base.Initialize(initializer);
    }

    public override void ProcessMessage(SoapMessage message)
    {
        // 检查请求头Content-Type是否为"application/xml"
        try
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeDeserialize:
                    if (message is SoapServerMessage 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)
        {

        }
    }
}

namespace ESB
{
    /// <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]
    public class WebService : System.Web.Services.WebService
    {
        public override object GetService(Type service)
        {
            return base.GetService(service);
        }

        public WebService()
        {
            //this.Application.sa
            this.Context.Request.ContentType = "application/xml";
        }

        [WebMethod(Description = "调用业务")]
        [ESBSoapExtension(Priority =1)]
        public string callBussiness(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>
        private string WebServiceAnalysis(System.Web.HttpRequest request, string name)
        {
            try
            {
                if (request.ContentLength == 0)
                {
                    throw new Exception($"Body(xml数据) 无数据");
                }
                // 获取请求内容
                Stream inputStream = request.InputStream;
                // 重新获取内容
                inputStream.Position = 0;
                // 读取请求主体内容
                using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
                {
                    string requestBody = reader.ReadToEnd();
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(requestBody);

                    XmlNode strNode = xmlDoc.SelectSingleNode($"//{name}");

                    if (strNode != null)
                    {
                        return strNode.InnerText;
                    }
                    else
                    {
                        throw new Exception($"未在Body(xml数据)找到{name}节点");
                    }
                }
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用C#的`HttpClient`类来调用WebService接口,并传递参数和接收返回值。以下是一个示例代码: ```csharp using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Xml; namespace WebServiceExample { class Program { static async Task Main(string[] args) { // 接口地址 string url = "http://10.10.47.132:8103/soap/IWebService"; // 创建HttpClient对象 HttpClient client = new HttpClient(); // 创建SOAP请求内容 string soapRequest = @"<?xml version=""1.0"" encoding=""utf-8""?> <soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""> <soap:Body> <YourMethodName xmlns=""YourNamespace""> <Param1>Value1</Param1> <Param2>Value2</Param2> </YourMethodName> </soap:Body> </soap:Envelope>"; // 设置请求头部信息 client.DefaultRequestHeaders.Add("SOAPAction", "YourSOAPAction"); // 发送请求并获取响应 HttpResponseMessage response = await client.PostAsync(url, new StringContent(soapRequest, Encoding.UTF8, "text/xml")); // 读取响应内容 string responseContent = await response.Content.ReadAsStringAsync(); // 解析XML响应 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(responseContent); // 提取返回值 XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlDoc.NameTable); nsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"); nsManager.AddNamespace("ns", "YourNamespace"); XmlNode resultNode = xmlDoc.SelectSingleNode("//ns:YourMethodNameResponse/ns:YourMethodNameResult", nsManager); string result = resultNode.InnerText; // 输出返回值 Console.WriteLine("返回值: " + result); } } } ``` 你需要将上述代码中的以下部分进行替换: - `url`:将其替换为你的WebService接口地址。 - `soapRequest`:将其替换为你的SOAP请求内容。 - `"YourMethodName"`:将其替换为你要调用的WebService方法名。 - `"YourNamespace"`:将其替换为你的命名空间。 - `"YourSOAPAction"`:将其替换为你的SOAPAction。 请确保你的应用程序具有访问WebService接口的权限,并根据实际情况修改代码以适应你的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值