SoapCore .NET6.0迁移WCF服务遇Content-Type错误求助
SoapCore迁移至.NET6后JS客户端调用报Content-Type错误
问题详情
迁移WCF服务到.NET6使用SoapCore时,JS客户端调用抛出错误:
System.InvalidOperationException: Incorrect Content-Type: text/xml; charset=UTF-8
客户端请求信息:
- URL:
/ServicioAvisos/WebAvisos/GetRemoteControl - 请求体:
<GetRemoteControl xmlns="http://tempuri.org/"><Id>0</Id></GetRemoteControl> - 请求头:
Content-Type:text/xml; charset=UTF-8X-Requested-With:XMLHttpRequest
问题原因
- 端点路由不匹配:SoapCore的SOAP服务采用单一端点模式,客户端不应在URL中追加方法名,需直接请求服务根端点。
- 参数绑定错误:实现类中使用了WebAPI的
[FromBody]特性,不符合SOAP服务的参数绑定逻辑,且参数名与接口定义不一致(接口为Id,实现类为ObjId)。 - SOAP版本配置缺失:未明确指定SOAP版本,SoapCore默认可能期望SOAP 1.2的
application/soap+xml类型,与客户端的text/xml(SOAP 1.1)不兼容。 - 中间件顺序错误:重复调用
UseRouting,且UseAuthorization位置不正确,影响请求管道处理。
解决方案
1. 修正SoapCore端点配置
确保端点为服务根地址,且指定SOAP 1.1版本(匹配客户端的text/xml Content-Type)。
2. 调整服务实现代码
移除[FromBody]特性,统一参数名与接口定义一致。
3. 修正中间件顺序
移除重复的UseRouting,确保中间件按正确顺序执行。
4. 兼容旧客户端URL(可选)
若无法修改客户端请求URL,可添加URL重写规则,将带方法名的请求转发到服务端点。
修改后的代码示例
Program.cs
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddXmlSerializerFormatters() .AddXmlDataContractSerializerFormatters(); builder.Services.AddSoapCore(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddSingleton<IWebAvisos, RemoteControlService>(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); // 配置SoapCore端点,指定SOAP 1.1编码器 app.UseEndpoints(endpoints => { var soapOptions = new SoapEncoderOptions { WriteEncoding = System.Text.Encoding.UTF8 }; // 指定SOAP 1.1,对应Content-Type: text/xml endpoints.UseSoapEndpoint<IWebAvisos>( "/ServicioAvisos/WebAvisos", soapOptions, SoapSerializer.XmlSerializer, SoapProtocolVersion.Soap11); }); // 可选:添加URL重写,兼容旧客户端的带方法名URL app.UseRewriter(new RewriteOptions() .AddRewrite(@"^ServicioAvisos/WebAvisos/GetRemoteControl$", "ServicioAvisos/WebAvisos", skipRemainingRules: true)); app.Run();
接口IWebAvisos
[ServiceContract(Namespace = "http://tempuri.org/")] public interface IWebAvisos { [OperationContract] List<string> GetRemoteControl(int Id); }
注意:添加
Namespace属性,与客户端请求体中的xmlns一致。
实现类RemoteControlService
public class RemoteControlService : IWebAvisos { public List<string> GetRemoteControl(int Id) { return new List<string>() { "1", "2" }; } }
客户端请求调整(若可修改)
将请求URL改为服务根端点,请求体保持不变:
- URL:
/ServicioAvisos/WebAvisos - 请求头:
Content-Type:text/xml; charset=UTF-8
内容的提问来源于stack exchange,提问作者Xar
相关产品推荐
相关产品推荐

