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

如何以二进制编码格式发送WCF请求?自定义绑定服务报错求助

解决WCF二进制编码请求报错及发送方法

错误原因分析

你遇到的Cannot process the message because the content type 'application/xml' was not the expected type 'application/soap+msbin1'错误,核心原因很明确:你的WCF服务配置了**二进制SOAP编码(MSBin1)**的自定义绑定,但你用HttpClient发送的是默认XML格式的请求,内容类型和服务期望的不匹配,导致服务无法解析请求。

解决方案

下面提供两种可行的解决方式,优先推荐第一种(更简单、不易出错):


方式1:使用WCF客户端代理(推荐)

WCF本身提供了成熟的客户端代理机制,能自动适配服务端的绑定编码,不用手动处理二进制序列化:

  1. 生成服务代理:
    • 在Visual Studio中右键项目 → 添加 → 服务引用,输入服务的WSDL地址,生成代理类和配置文件。
    • 或者用命令行工具SvcUtil.exe生成:
      SvcUtil.exe http://your-service-url?wsdl /out:ServiceProxy.cs /config:App.config
      
  2. 配置自定义绑定:
    确保客户端的绑定配置和服务端一致,核心是包含BinaryMessageEncodingBindingElement,比如App.config里的配置:
    <bindings>
      <customBinding>
        <binding name="YourCustomBinding">
          <binaryMessageEncoding />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="http://your-service-url" binding="customBinding" bindingConfiguration="YourCustomBinding" contract="YourServiceContract" name="YourEndpoint" />
    </client>
    
  3. 调用服务的代码:
    public static void Test(string username, string password)
    {
        // 使用生成的代理类
        using (var client = new YourServiceClient("YourEndpoint"))
        {
            // 设置凭证(如果需要)
            client.ClientCredentials.UserName.UserName = username;
            client.ClientCredentials.UserName.Password = password;
            // 调用服务方法
            var result = client.YourServiceMethod();
        }
    }
    

方式2:手动用HttpClient发送二进制编码请求

如果必须使用HttpClient(比如特定场景限制),需要手动将SOAP消息序列化为MSBin1格式,步骤如下:

  1. 引用必要的程序集:
    确保项目引用了System.ServiceModel、System.ServiceModel.Channels、System.Runtime.Serialization。
  2. 构造并序列化二进制SOAP消息:
    public static void Test(string username, string password)
    {
        // 1. 创建和服务端一致的自定义绑定
        var binding = new CustomBinding();
        binding.Elements.Add(new BinaryMessageEncodingBindingElement());
        binding.Elements.Add(new HttpTransportBindingElement());
    
        // 2. 构造SOAP请求消息(注意Action要和服务端契约一致)
        var message = Message.CreateMessage(binding.MessageVersion, "http://your-service-namespace/YourServiceMethod", 
            new YourRequestType { Username = username, Password = password });
    
        // 3. 将消息序列化为字节数组(MSBin1格式)
        var encoder = binding.CreateBindingElements().Find<MessageEncodingBindingElement>().CreateMessageEncoderFactory().Encoder;
        byte[] messageBytes;
        using (var ms = new MemoryStream())
        {
            encoder.WriteMessage(message, ms);
            messageBytes = ms.ToArray();
        }
    
        // 4. 用HttpClient发送请求
        using (var client = new HttpClient(new HttpClientHandler()))
        {
            var request = new HttpRequestMessage(HttpMethod.Post, "http://your-service-url")
            {
                Content = new ByteArrayContent(messageBytes)
            };
            // 设置服务期望的Content-Type
            request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/soap+msbin1");
            // 如果需要身份验证,添加凭证示例
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", 
                Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}")));
    
            var response = client.SendAsync(request).Result;
            response.EnsureSuccessStatusCode();
            // 处理响应(如果需要)
            var responseBytes = response.Content.ReadAsByteArrayAsync().Result;
            var responseMessage = encoder.ReadMessage(new MemoryStream(responseBytes), int.MaxValue);
        }
    }
    

关键注意点

  • 确保客户端的绑定配置(尤其是消息编码、MessageVersion部分)和服务端完全一致,否则会出现编码不兼容的问题。
  • 手动构造SOAP消息时,消息的Action必须和服务端契约中定义的方法Action完全匹配,否则服务无法识别请求的目标方法。

内容的提问来源于stack exchange,提问作者KrishOnline

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:13:44