C#怎么调用WebService接口?C#如何动态调用SOAP WebService?

来源:程序开发作者:长沙网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《C#怎么调用WebService接口?C#如何动态调用SOAP WebService?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么调用WebService接口?C#如何动态调用SOAP WebService?》有用,将其分享出去将是对创作者最好的鼓励。

在C#项目开发中,对接第三方或内部系统的SOAP类型WebService接口是常见任务,根据接口稳定性不同,我们可以选择静态引用或动态调用两种实现方式,其中动态调用无需提前添加服务引用,适配性更强。

C#怎么调用WebService接口?C#如何动态调用SOAP WebService?

C#调用WebService的两种常用方式

1. 静态引用方式

静态引用适合WebService接口地址、方法定义长期固定的场景,操作步骤如下:

  • 在Visual Studio项目中右键点击引用,选择添加服务引用
  • 输入WebService的WSDL地址,设置命名空间后完成引用
  • 直接实例化服务类,调用对应方法即可

这种方式操作简单,有智能提示,但是接口发生变动时需要重新更新引用,不够灵活。

2. 动态调用方式

动态调用不需要提前添加服务引用,通过拼接SOAP请求报文、发送HTTP请求、解析返回结果的方式实现调用,适合接口地址或方法可能变化的场景。

动态调用SOAP WebService的完整实现

核心实现步骤

  • 获取WebService的WSDL描述,确认方法的命名空间、参数格式、SOAPAction等信息
  • 拼接符合SOAP协议的XML请求报文
  • 设置HTTP请求头,包含Content-Type和SOAPAction
  • 发送POST请求到WebService地址,获取返回报文
  • 解析返回的XML结果,提取需要的业务数据

完整代码示例

以下是动态调用WebService的通用工具类代码:

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;

public class WebServiceHelper
{
    /// <summary>
    /// 动态调用SOAP WebService接口
    /// </summary>
    /// <param name="url">WebService地址</param>
    /// <param name="methodName">调用的方法名</param>
    /// <param name="soapAction">SOAPAction值,可从WSDL中获取</param>
    /// <param name="params">方法参数,key为参数名,value为参数值</param>
    /// <returns>接口返回的结果字符串</returns>
    public static string CallWebService(string url, string methodName, string soapAction, System.Collections.Generic.Dictionary<string, string> params)
    {
        // 拼接SOAP请求报文
        StringBuilder soapBuilder = new StringBuilder();
        soapBuilder.Append("<?xml version="1.0" encoding="utf-8"?>");
        soapBuilder.Append("<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ");
        soapBuilder.Append("xmlns:xsd="http://www.w3.org/2001/XMLSchema" ");
        soapBuilder.Append("xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">");
        soapBuilder.Append("<soap:Body>");
        // 方法节点,注意命名空间需要和WSDL中的一致
        soapBuilder.Append($"<{methodName} xmlns="http://tempuri.org/">");
        // 拼接参数
        if (params != null)
        {
            foreach (var item in params)
            {
                soapBuilder.Append($"<{item.Key}>{item.Value}</{item.Key}>");
            }
        }
        soapBuilder.Append($"</{methodName}>");
        soapBuilder.Append("</soap:Body>");
        soapBuilder.Append("</soap:Envelope>");

        string soapXml = soapBuilder.ToString();
        byte[] requestData = Encoding.UTF8.GetBytes(soapXml);

        // 创建HTTP请求
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "POST";
        request.ContentType = "text/xml; charset=utf-8";
        request.Headers.Add("SOAPAction", soapAction);
        request.ContentLength = requestData.Length;

        // 写入请求数据
        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(requestData, 0, requestData.Length);
        }

        // 获取响应并解析
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            using (Stream responseStream = response.GetResponseStream())
            {
                using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
        }
    }

    /// <summary>
    /// 从返回的SOAP XML中提取方法返回结果
    /// </summary>
    /// <param name="soapResult">SOAP返回报文</param>
    /// <param name="resultNodeName">返回结果节点名,通常为方法名加Result</param>
    /// <returns>解析后的结果</returns>
    public static string ParseSoapResult(string soapResult, string resultNodeName)
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(soapResult);
        // 命名空间管理
        XmlNamespaceManager nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
        nsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
        nsManager.AddNamespace("ns", "http://tempuri.org/");
        // 定位结果节点
        XmlNode resultNode = xmlDoc.SelectSingleNode($"//ns:{resultNodeName}", nsManager);
        return resultNode?.InnerText;
    }
}

调用示例

假设有一个获取用户信息的WebService,地址为http://ipipp.com/UserService.asmx,方法名为GetUserInfo,SOAPAction为http://tempuri.org/GetUserInfo,参数为userId,调用代码如下:

class Program
{
    static void Main(string[] args)
    {
        string url = "http://ipipp.com/UserService.asmx";
        string methodName = "GetUserInfo";
        string soapAction = "http://tempuri.org/GetUserInfo";
        var params = new System.Collections.Generic.Dictionary<string, string>
        {
            { "userId", "1001" }
        };
        // 调用接口
        string soapResult = WebServiceHelper.CallWebService(url, methodName, soapAction, params);
        // 解析结果,返回结果节点名为GetUserInfoResult
        string userInfo = WebServiceHelper.ParseSoapResult(soapResult, "GetUserInfoResult");
        Console.WriteLine($"用户信息:{userInfo}");
    }
}

注意事项

  • SOAP请求报文中的命名空间需要和WSDL描述中的完全一致,否则会返回调用失败的错误
  • 如果WebService需要身份验证,需要在请求头中添加对应的认证信息,比如Basic认证的用户名密码
  • 返回结果解析时如果命名空间不匹配,会导致无法获取节点,需要提前确认WSDL中的命名空间定义
  • 动态调用方式没有智能提示,需要提前确认方法的参数名称、类型,避免拼接错误

C#SOAP_WebService动态调用接口调用修改时间:2026-06-17 07:57:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。