如何以二进制编码格式发送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本身提供了成熟的客户端代理机制,能自动适配服务端的绑定编码,不用手动处理二进制序列化:
- 生成服务代理:
- 在Visual Studio中右键项目 → 添加 → 服务引用,输入服务的WSDL地址,生成代理类和配置文件。
- 或者用命令行工具
SvcUtil.exe生成:SvcUtil.exe http://your-service-url?wsdl /out:ServiceProxy.cs /config:App.config
- 配置自定义绑定:
确保客户端的绑定配置和服务端一致,核心是包含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> - 调用服务的代码:
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格式,步骤如下:
- 引用必要的程序集:
确保项目引用了System.ServiceModel、System.ServiceModel.Channels、System.Runtime.Serialization。 - 构造并序列化二进制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
相关产品推荐
相关产品推荐

