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

news2024/11/15 13:26:43

一、问题描述

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;
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1078915.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机竞赛YOLOv7 目标检测网络解读

文章目录 0 前言1 yolov7的整体结构2 关键点 - backbone关键点 - head3 训练4 使用效果5 最后 0 前言 世界变化太快&#xff0c;YOLOv6还没用熟YOLOv7就来了&#xff0c;如果有同学的毕设项目想用上最新的技术&#xff0c;不妨看看学长的这篇文章&#xff0c;学长带大家简单的…

如何为您的 Linux 服务器设置简单的 Grafana 云监控仪表板

Grafana 是一个开源可观察性平台,用于创建可视化数据集的仪表板。您可以使用它方便地监控服务器统计信息,例如 CPU 消耗、网络吞吐量和正常运行时间。 Grafana可以自托管,也可以通过官方Grafana Cloud实例作为 SaaS 解决方案进行访问。在本文中,您将了解如何设置 Grafana …

修炼k8s+flink+hdfs+dlink(四:k8s(一)概念)

一&#xff1a;概念 1. 概述 1.1 kubernetes对象. k8s对象包含俩个嵌套对象字段。 spec&#xff08;规约&#xff09;&#xff1a;期望状态 status&#xff08;状态&#xff09;&#xff1a;当前状态 当创建对象的时候&#xff0c;会按照spec的状态进行创建&#xff0c;如果…

scratch芝麻开门 2023年9月中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析

目录 scratch芝麻开门 一、题目要求 1、准备工作 2、功能实现 二、案例分析

操作系统学习笔记3-同步互斥问题

文章目录 1 同步与互斥逻辑图2、并发性异步性独立性3、临界资源临界区4、同步与互斥 1 同步与互斥逻辑图 2、并发性异步性独立性 3、临界资源临界区 4、同步与互斥

汽车一键启动点火开关按键一键启动按钮型号规格

汽车点火开关/移动管家一键启动按键/汽车改装引擎启动按钮型号&#xff1a;YD828溥款开关 一键启动按钮&#xff08;适用于配套启动主机使用或原车一键启动开关更换&#xff09; 1.适合配套专用板板安装 2.开孔器开孔安装 3.原车钥匙位安装 外观&#xff1a;黑色 按钮上有3种不…

【融合ChatGPT等AI模型】Python-GEE遥感云大数据分析、管理与可视化及多领域案例实践应用

目录 第一章 理论基础 第二章 开发环境搭建 第三章 遥感大数据处理基础与ChatGPT等AI模型交互 第四章 典型案例操作实践 第五章 输入输出及数据资产高效管理 第六章 云端数据论文出版级可视化 更多应用 随着航空、航天、近地空间等多个遥感平台的不断发展&#xff0c;近…

免费的ChatGPT与StableDiffusion AI绘画 二合一 附在线地址

ChatGPT与StableDiffusion 在线地址在文末 介绍 嘿&#xff0c;大家好&#xff01;今天我要给大家介绍一个非常酷炫的技术结合——ChatGPT与StableDiffusion的合作。听起来是不是很有趣&#xff1f;那么&#xff0c;让我们一起来看看这个组合到底能带给我们什么样的奇妙体验…

Go图片文件按照时间戳如何排序

涉及点包括 文件创建;时间控制器;自建封装包以及方法; 模板渲染;路由配置;不同的数据类型之间的转换拼接; 对于之前进行的文件上传操作,囊括单文件以及同名多文件和非同名多文件的编程方法,在生产中会遇到一个问题,如果上传的图片是同名的,那么在单文件上传的时候会将…

java 每种设计模式的作用,与应用场景

文章目录 前言java 每种设计模式的作用&#xff0c;与应用场景 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且听说点赞的人每天的运气都不会太差&#xff0c;实在白嫖的话&#xff0…

Android - Context

一、概念 Context 是应用程序和系统之间的桥梁&#xff0c;用于获取全局消息、访问系统资源、调用应用程序级的操作。一般直接调用 Context 的方法或者调用接口时传入Context。 Android应用模型是基于组件的应用设计模式&#xff0c;组件的运行要有一个完整的Android工程环境。…

Linux基础指令笔记大全

Linux基础指令笔记大全 1. ls 指令2. pwd命令3. cd 指令4. touch指令5. mkdir指令6. rmdir指令 && rm 指令7. man指令8.cp指令9. mv指令10. cat 指令11. more指令12. less指令13. head指令14. tail指令15. 时间相关的指令1. **在显示方面&#xff0c;使用者可以设定欲显…

华为云云耀云服务器L实例评测 | 实例使用教学之综合导览

华为云云耀云服务器L实例评测 &#xff5c; 实例使用教学之综合导览 实例使用教学实例场景体验实例性能评测实例评测使用介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什么华为云云耀云…

上海亚商投顾:沪指探底回升 华为汽车概念股集体大涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日探底回升&#xff0c;早盘一度集体跌超1%&#xff0c;随后震荡回暖&#xff0c;深成指、创业板指…

hive 知识总结

​编辑 社区公告教程下载分享问答JD 登 录 注册 01 hive 介绍与安装 1 hive介绍与原理分析 Hive是一个基于Hadoop的开源数据仓库工具&#xff0c;用于存储和处理海量结构化数据。它是Facebook 2008年8月开源的一个数据仓库框架&#xff0c;提供了类似于SQL语法的HQL&#xf…

第 5 章 数组和广义表(数组的顺序存储结构实现)

1. 背景说明 数组一旦被定义&#xff0c;它的维数和维界就不再改变。因此&#xff0c;除了结构的初始化和销毁之外&#xff0c;数组只有存取元素和修改元素值的操作。 2. 示例代码 1) status.h /* DataStructure 预定义常量和类型头文件 */ #include <string.h>#ifndef…

【论文精读】Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 前言Abstract1 Introduction2 Chain-of-Thought Prompting3 Arithmetic Reasoning3,1 Experimental Setup3.2 Results3.3 Ablation Study3.4 Robustness of Chain of Thought 4 Commonsense Reasoning5…

通过Java Record提升代码质量:简洁而健壮的数据对象

为了提高开发效率和代码可读性&#xff0c;Java 14引入了一个新的特性 - Records&#xff08;记录类型&#xff09;。Records旨在简化和改进Java中的数据类定义&#xff0c;使得创建简单的数据传输对象&#xff08;DTO&#xff09;或值对象更加便捷。 什么是Java Record&#x…

Springboot接收http参数总结(最简单易懂)

1. 前端能携带请求参数的地方 http请求一半前端请求参数放在三个地方&#xff1a;请求头&#xff0c;请求查询参数&#xff08;Query String&#xff09;&#xff0c;请求体。 请求体需要获取HttpServletRequest对象才能获取。 2. 请求体常见格式 而请求体中可以存放多种格式…

Leetcode92. 反转链表 II

Every day a Leetcode 题目来源&#xff1a;92. 反转链表 II 解法1&#xff1a;模拟 注意 STL 的 reverse() 是左闭右开的。 代码&#xff1a; class Solution { public:ListNode *reverseBetween(ListNode *head, int left, int right){vector<int> nums getNums(…