• 【WebService】C#搭建的标准WebService接口,在使ESB模版作为参数无法获取参数数据


    一、问题说明

    1.1 问题描述

    使用C# 搭建WebService接口,并按照ESB平台人员的要求,将命名空间改为"http://esb.webservice",使用Postman+ESB平台人员提供的入参示例进行测试时,callBussiness接口参数message始终为null

    以下是ESB平台提供的模版

    
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:esb="http://esb.webservice">
       <soapenv:Header/>
       <soapenv:Body>
          <esb:callBussiness>
             
             <message>
            
             message>
          esb:callBussiness>
       soapenv:Body>
    soapenv:Envelope>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    1.2 C# WebService代码

    using System;
    using System.IO;
    using System.Text;
    using System.Web.Services;
    using System.Xml;
    using System.Xml.Serialization;
    using Rss_WebServer.code;
    
    namespace ESB
    {
        /// 
        /// WebService 的摘要说明
        /// 
        [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
        {
            [WebMethod(Description = "调用业务")]
            public string callBussiness(string message)
            {
               return message; 
            }
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    1.3 Postman 测试参数

    • POST http://localhost:55305/WebService.asmx?op=callBussiness
    • Headers
    KEYVALUEDESCRIPTION
    Content-Typetext/xml; charset=utf-8
    SOAPAction“http://esb.webservice/callBussiness”
    • Body
      • raw XML(text/xml)
    
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:esb="http://esb.webservice">
       <soapenv:Header/>
       <soapenv:Body>
          <esb:callBussiness>
             
             <message>
            少莫千华370763160@qq.com]]>
             message>
          esb:callBussiness>
       soapenv:Body>
    soapenv:Envelope>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    在这里插入图片描述

    二、问题分析

    根本问题是ESB平台提供的参数模版并没有完全按照标准的WebService协议进行编写,导致使用官方搭建的WebService接口无法正常的解析参数,所以要想解决此问题,有两个途径:

    • 与ESB平台人员沟通,要求其标准化参数模版
    • 自己重新解构WebService参数

    三、解决方案

    3.1 与ESB平台人员沟通,要求其标准化参数模版

    3.1.1 标准模版 - 使用命名空间缩写

    callBussiness接口的message参数添加命名空间缩写esb

    
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:esb="http://esb.webservice">
       <soapenv:Header/>
       <soapenv:Body>
          <esb:callBussiness>
             
             <esb:message>
            
             esb:message>
          esb:callBussiness>
       soapenv:Body>
    soapenv:Envelope>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.1.1 标准模版 - 使用完整的命名空间

    callBussiness接口的使用完整的命名空间

    
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
       <soapenv:Header/>
       <soapenv:Body>
          <callBussiness xmlns="http://esb.webservice">
             
             <message>
            
             message>
          callBussiness>
       soapenv:Body>
    soapenv:Envelope>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.2 自己重新解构WebService参数

    从请求对象base.Context.Request中重新获取所有Body内容(InputStream),然后再进行自定义解析。
    :因为是搭建的标准的WebService接口Body内容(InputStream)在进去函数内部前已经被SOAP协议解析过一次,所以InputStream起始内容位置Position 指向数据流的结尾,所以在读取之前,先要将InputStream起始内容位置Position设置为0,否则读取的内容为空('')

    using System;
    using System.IO;
    using System.Text;
    using System.Web.Services;
    using System.Xml;
    using System.Xml.Serialization;
    using Rss_WebServer.code;
    namespace ESB
    {
        /// 
        /// WebService 的摘要说明
        /// 
        [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
        {
            [WebMethod(Description = "调用业务")]
            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;
                }
                
            }
            /// 
            /// 重新解析 WebService
            /// 
            /// 
            /// 
            /// 
            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;
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
  • 相关阅读:
    解决mybatis用Map返回的字段全变大写的问题
    元宇宙产业委甘华鸣:关于术语“元宇宙”以及相关问题
    CSS(ellipsis) 用百分比宽度将字符串溢出部分显示为省略号
    在Mysql中新建序列Sequence
    【苍穹外卖 | 项目日记】第七天
    C语言函数复习全解析:参数、无参、嵌套与递归
    如何使用JMeter测试导入接口/导出接口
    docker系列文章目录
    基于Javaweb的流动市场地摊管理系统
    VI/VIM的使用
  • 原文地址:https://blog.csdn.net/chenlu5201314/article/details/133697297