.NetCore调用Soap接口


前言

添加服务引用的方式无法满足我请求Soap接口,所以写了个Soap帮助类,使用HttpClient的方式请求接口。


提示:以下是本篇文章正文内容,下面案例可供参考

一、简单的介绍一下Soap语法

一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:

  • 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
  • 可选的 Header 元素,包含头部信息
  • 必需的 Body 元素,包含所有的调用和响应信息
  • 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息

Soap消息的基本结构

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
...
</soap:Header>

<soap:Body>
...
  <soap:Fault>
  ...
  </soap:Fault>
</soap:Body>

</soap:Envelope>

二、使用步骤

1.修改appsettings.json配置文件

在配置文件中添加Soap接口配置项,比如请求的Soap接口地址、用户和密码等。

代码如下(示例):

  "Soap": {
    "Address": "https://xxx.com/xxx/soap",
    "LoginId": "xxxxxx",
    "Password": "xxxxxx"
  },

2.新建SoapOptions类

SoapOptions类用于跟appsettings.json配置文件中的soap配置项做映射,方便使用。

代码如下(示例):

    /// <summary>
    /// 接口配置项
    /// </summary>
    public class JetPlanSoapOptions
    {
        /// <summary>
        /// 请求地址
        /// </summary>
        public string Address { get; set; }
        /// <summary>
        /// 认证ID
        /// </summary>
        public string LoginId { get; set; }
        /// <summary>
        /// 认证密码
        /// </summary>
        public string Password { get; set; }
    }

在Startup文件中的ConfigureServices方法里给配置项做映射,在这里我用的是Abp的框架,所以在契约模块ContractsModule中添加。

var Configuration = context.Services.GetConfiguration();
context.Services.Configure<CFPSoapOptions>(Configuration.GetSection("CFPSoap"));

3.新建Soap帮助类

代码如下(示例):

   public class SoapHelper
    {
        private readonly SoapOptions _options;

        public SoapClient(IOptions<SoapOptions> options)
        {
            _options = options.Value;
        }

        public async Task<XDocument> RequestAsync(CdbRequest cdbRequest)
        {
            string soapXml = @$"
<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
    <soapenv:Body>
        <JP_CustDB_Request>
           <custID>{_options.CustId}</custID>
           <custPwd>{_options.CustPwd}</custPwd>
           {cdbRequest}
        </JP_CustDB_Request>
    </soapenv:Body>
</soapenv:Envelope>";

            var httpClientHandler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (message, cert, chain, error) => true
            };
            HttpClient client = new HttpClient(httpClientHandler);

            HttpContent content = new StringContent(soapXml, Encoding.UTF8, "text/xml");
            content.Headers.Add("loginid", _options.LoginId);
            content.Headers.Add("password", _options.Password);

            var response = await client.PostAsync(_options.Address, content);
            var responseXml = await response.Content.ReadAsStringAsync();

            XDocument doc = XDocument.Parse(responseXml);

            var error = doc.Descendants(JetPlanCDBSoap.ErrorText).FirstOrDefault();
            if (error != null)
            {
                throw new Exception(error.Value);
            }

            return doc;
        }

        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="doc"></param>
        /// <param name="dbData"></param>
        /// <returns></returns>
        public T Deserialize<T>(XDocument doc, string dbData) where T : class
        {
            var data = doc.Descendants(dbData).First();
            var serializer = new XmlSerializer(typeof(T));
            var result = serializer.Deserialize(data.CreateReader()) as T;
            return result;
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public string Serialize<T>(T t) where T : class
        {
            var serializer = new XmlSerializer(typeof(T));
            var str = new StringBuilder();
            XmlWriter writer = XmlWriter.Create(str);
            serializer.Serialize(writer, t);
            return str.ToString();
        }

        /// <summary>
        /// 生成请求内容
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public string MakeRequestContent<T>(T t) where T : class, new()
        {
            var xmlStr = Serialize(t);
            var doc = XDocument.Parse(xmlStr);
            var des = doc.Descendants(JetPlanCDBSoap.CDBRequest);
            var arr = des.First().Elements().Select(x => x);
            return string.Join("", arr);
        }
    }

4.新建请求参数类

   public class CdbRequest
    {
        /// <summary>
        /// Soap接口请求内容
        /// </summary>
        private readonly string RequestContent;

        public CdbRequest(string requestContent)
        {
            RequestContent = requestContent;
        }

        public CdbRequest()
        {

        }
    }

5.调用

   CdbRequest request = new CdbRequest(requestContent);
   var doc = await _soapClient.RequestAsync(request);

总结

请求Soap的过程还是比较简单的,大概就是根据参数请求Soap接口,把响应后的XML数据进行处理。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值