ASP.NET Web Api流式模型绑定报错:Unsupported Media Type
解决ASP.NET Web API中流传输Payload时的"Unsupported Media Type"错误
问题根源
出现"Unsupported Media Type"(415错误)的核心原因是:发送请求时未指定正确的Content-Type请求头。ASP.NET Web API的模型绑定器需要明确请求体的媒体类型(如JSON),才能将流中的数据正确反序列化为DocumentEntity对象。
解决方案
1. 为请求添加Content-Type头
首先需要在请求模型中增加内容类型属性,并在发送请求时设置对应头信息:
更新请求模型
public class HttpCommunicationRequest { public bool IsPlatformService { get; set; } public string Url { get; set; } public HttpMethod Method { get; set; } public Stream Data { get; set; } // 新增:指定内容类型字段 public string ContentType { get; set; } = "application/json"; }
在IHttpCommunicator.Send方法中设置请求头
假设Send方法基于HttpClient实现,需要将流包装为StreamContent并设置媒体类型:
public async Task<HttpCommunicationResponse> Send(HttpCommunicationRequest request) { using var httpClient = new HttpClient(); using var content = new StreamContent(request.Data); // 绑定Content-Type头 content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(request.ContentType); var httpRequest = new HttpRequestMessage(request.Method, request.Url) { Content = content }; var response = await httpClient.SendAsync(httpRequest); // 处理响应并返回HttpCommunicationResponse // ... }
2. 确保序列化格式与Content-Type匹配
确认_objectSerializer.SerializeToStream生成的数据流格式和指定的Content-Type一致:
- 若序列化输出为JSON,
Content-Type设为application/json - 若为XML,设为
application/xml
3. 重置流的读取位置
在将流传递给请求前,必须将流指针重置到起始位置,否则接收端会读取到空数据:
var stream = _objectSerializer.SerializeToStream(payload); stream.Position = 0; // 重置流指针到开头
4. 修正请求路由路径(可选)
原代码中Action2的完整路由是api/v1/test/Action2,但请求URL写的是https://localhost:3333/api/v1/Action2,缺少test前缀,可能导致404错误,需同步修正:
Url = "https://localhost:3333/api/v1/test/Action2"
5. 显式标记参数来源(可选)
虽然[ApiController]会自动推断从请求体绑定参数,但显式添加[FromBody]属性可增强代码可读性:
[HttpPost] [Route("Action2")] public IActionResult Action2([FromBody] DocumentEntity documentEntity) { return new JsonResult(new { Success = true }); }
完整修改后的Action1代码
[HttpPost] [Route("Action1")] public async Task<IActionResult> Action1() { var payload = new DocumentEntity { Id = Guid.NewGuid().ToString(), Name = "My Document", Content = System.IO.File.ReadAllBytes(@"2705 v1 1.docx") }; var stream = _objectSerializer.SerializeToStream(payload); stream.Position = 0; // 重置流指针 var httpCommunicationRequest = new HttpCommunicationRequest { IsPlatformService = true, Url = "https://localhost:3333/api/v1/test/Action2", Method = HttpMethod.Post, Data = stream, ContentType = "application/json" }; var httpCommunicationResponse = await _httpCommunicator.Send(httpCommunicationRequest); return new JsonResult(httpCommunicationResponse); }
内容的提问来源于stack exchange,提问作者VJAI
相关产品推荐
相关产品推荐

