【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 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.3 Postman 测试参数

  • POST http://localhost:55305/WebService.asmx?op=callBussiness
  • Headers
KEY VALUE DESCRIPTION
Content-Type text/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>
        少莫千华[email protected]]]>
         message>
      esb:callBussiness>
   soapenv:Body>
soapenv:Envelope>

【WebService】C#搭建的标准WebService接口,在使ESB模版作为参数无法获取参数数据_第1张图片

【WebService】C#搭建的标准WebService接口,在使ESB模版作为参数无法获取参数数据_第2张图片

二、问题分析

根本问题是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>

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>

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

你可能感兴趣的:(语言-CSharp,c#,WebService,Soap,ESB,callBussiness)