You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何结合WebRequest与对象调用SOAP的createEvents方法(Basic Auth)

嘿,我来帮你解决这个C#发送SOAP POST请求的问题!你已经有了BusinessEvent对象和WebRequest的基础配置,现在关键是把这些和createEvents方法结合起来——其实有两种常用方案,我给你详细拆解下:

方案一:用代理类(推荐,最省心)

如果服务端提供了WSDL文件,直接用微软的svcutil.exe生成代理类是最简单的方式,它会帮你自动处理SOAP序列化、认证和MTOM这些细节,不用手动拼XML。

步骤:

  1. 打开Visual Studio的开发者命令提示符,运行生成命令:

    svcutil.exe https://eu3.provider.com/eTech/services/cxf/v6/BusinessEventManager?wsdl /out:BusinessEventManager.cs
    

    这会生成一个包含代理类的.cs文件,把它加到你的项目里。

  2. 然后直接调用方法,同时配置HTTP Basic Auth:

    // 实例化代理客户端(类名可能根据WSDL生成的不同略有变化)
    var eventManagerClient = new BusinessEventManagerClient();
    
    // 配置HTTPS下的Basic Auth
    eventManagerClient.ClientCredentials.UserName.UserName = "你的用户名";
    eventManagerClient.ClientCredentials.UserName.Password = "你的密码";
    
    // 构造你已经写好的BusinessEvent数组和WSEntry数组
    BusinessEvent[] events = new BusinessEvent[] { /* 你的BusinessEvent实例 */ };
    WSEntry[] entries = new WSEntry[] { /* 你的WSEntry实例 */ };
    
    // 直接调用createEvents方法
    var response = eventManagerClient.createEvents(events, entries);
    
    // 处理响应结果(如果有返回值的话)
    Console.WriteLine("请求成功,响应结果:" + response.ToString());
    
  3. 如果需要启用MTOM(比如你的事件里包含二进制数据),只需要给绑定配置MTOM编码:

    var binding = (BasicHttpBinding)eventManagerClient.Endpoint.Binding;
    binding.MessageEncoding = WSMessageEncoding.Mtom;
    

方案二:手动构造SOAP请求(适合不能生成代理的场景)

如果无法生成代理类,就需要手动把对象序列化成符合服务要求的SOAP XML,再通过WebRequest发送。

核心思路:

你需要把BusinessEvent[]和WSEntry[]序列化成XML,然后嵌入到SOAP 1.2的Envelope结构里,同时设置正确的HTTP头和Basic Auth。

代码示例:

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

// 假设你的BusinessEvent和WSEntry类已经正确定义(带正确的XmlAttribute/XmlElement特性)
public class SOAPRequestHelper
{
    public static void SendCreateEventsRequest(string username, string password, BusinessEvent[] events, WSEntry[] entries)
    {
        // 1. 初始化WebRequest
        var request = WebRequest.Create("https://eu3.provider.com/eTech/services/cxf/v6/BusinessEventManager");
        request.Method = "POST";
        // SOAP 1.2必须用这个Content-Type,别和SOAP 1.1的text/xml搞混
        request.ContentType = "application/soap+xml; charset=utf-8";

        // 2. 设置HTTP Basic Auth
        string authCredentials = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}"));
        request.Headers.Add("Authorization", $"Basic {authCredentials}");

        // 3. 构造SOAP Envelope并序列化对象
        var soapEnvelopeBuilder = new StringBuilder();
        soapEnvelopeBuilder.Append(@"
<soap12:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
                 xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" 
                 xmlns:soap12=""http://www.w3.org/2003/05/soap-envelope"">
  <soap12:Body>
    <createEvents xmlns=""http://provider.com/eTech/services/cxf/v6/"">"); // 这里的命名空间要和服务端一致

        // 序列化BusinessEvent数组
        var eventSerializer = new XmlSerializer(typeof(BusinessEvent[]), new XmlRootAttribute("businessEvents") { Namespace = "http://provider.com/eTech/services/cxf/v6/" });
        using (var writer = new StringWriter(soapEnvelopeBuilder))
        {
            eventSerializer.Serialize(writer, events);
        }

        // 序列化WSEntry数组
        var entrySerializer = new XmlSerializer(typeof(WSEntry[]), new XmlRootAttribute("wsEntries") { Namespace = "http://provider.com/eTech/services/cxf/v6/" });
        using (var writer = new StringWriter(soapEnvelopeBuilder))
        {
            entrySerializer.Serialize(writer, entries);
        }

        // 关闭SOAP标签
        soapEnvelopeBuilder.Append(@"
    </createEvents>
  </soap12:Body>
</soap12:Envelope>");

        // 4. 写入请求流
        byte[] requestData = Encoding.UTF8.GetBytes(soapEnvelopeBuilder.ToString());
        request.ContentLength = requestData.Length;
        using (var stream = request.GetRequestStream())
        {
            stream.Write(requestData, 0, requestData.Length);
        }

        // 5. 获取并处理响应
        try
        {
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                    string responseXml = reader.ReadToEnd();
                    // 这里可以把responseXml反序列化成对应的结果对象,或者直接处理XML
                    Console.WriteLine("请求成功,响应XML:" + responseXml);
                }
            }
        }
        catch (WebException ex)
        {
            // 捕获错误响应,比如401、500等
            using (var errorResponse = (HttpWebResponse)ex.Response)
            {
                using (var reader = new StreamReader(errorResponse.GetResponseStream()))
                {
                    string errorXml = reader.ReadToEnd();
                    Console.WriteLine("请求失败,错误信息:" + errorXml);
                }
            }
        }
    }
}

关键注意事项

  • 命名空间必须完全匹配:服务端的createEvents方法、BusinessEvent、WSEntry都有对应的XML命名空间,一定要从WSDL里找准确,否则服务端会识别不了请求参数。
  • SOAP版本不要搞错:SOAP 1.2的Content-Type是application/soap+xml,如果用成SOAP 1.1的text/xml,服务端会直接返回错误。
  • MTOM的处理:如果你的事件包含大文件或二进制数据,需要启用MTOM,手动构造的话要用到MtomMessageEncoder,或者直接用代理类的MTOM配置更简单。
  • 异常处理:一定要捕获WebException,因为SOAP服务的错误通常会返回HTTP错误码(比如401表示认证失败,500表示服务端异常),通过异常可以拿到详细的错误XML。

内容的提问来源于stack exchange,提问作者Rachel-Abc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:44:00