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

Web API 2迁移后PUT更新请求报415 Unsupported Media Type问题

迁移Web API 1到Web API 2时PUT请求返回415 Unsupported Media Type错误

我正在把旧版Web API 1应用迁移到VS2022的Web API 2,现在卡在更新方法上。

我搭建了RESTful服务器,每个数据库表对应一个控制器,用Entity Framework映射实体。客户端填充实体更新信息后发送到服务器执行更新,相关代码如下:

客户端VB.NET代码

Public Function UpdateCultivar(ByVal _entity As CultivarEntity) As Boolean
    Try
        url = "Cultivar/Update"
        ms = New MemoryStream()
        _serializer = New XmlSerializer(GetType(CultivarEntity))
        _serializer.Serialize(ms, _entity)
        ms.Position = 0
        streamContent = New StreamContent(ms)
        responseTask = client.PutAsync(url, streamContent)
        responseTask.Wait()
        responseMessage = responseTask.Result
        If responseMessage.IsSuccessStatusCode = True Then
            Return deserializeBooleanResponse(responseMessage.Content.ReadAsStringAsync.Result)
        Else
            ProcessClientError(responseMessage.Content.ReadAsStringAsync.Result)
            Return Nothing
        End If
    Catch ex As Exception
        ProcessClientException(ex)
        Return Nothing
    End Try
End Function

客户端已在其他代码中设置请求头为application/xml,将实体序列化为XML后发起PUT请求。

服务器端C#代码

[Route("Update")]
[HttpPut]
[AcceptVerbs("PUT")]
public HttpResponseMessage Put( [FromBody]  CultivarEntity _Entity)
{
    Boolean result;
    try
    {
        _Entity = new CultivarEntity();
        _serializer = new System.Xml.Serialization.XmlSerializer(_Entity.GetType());
        ioStream = new System.IO.MemoryStream();
        ioStream = Request.Content.ReadAsStreamAsync().Result;
        ioStream.Position = 0;
        _Entity = (CultivarEntity)_serializer.Deserialize(ioStream);
        result = _Accessor.UpdateCultivar(_Entity.cultivar_pk, _Entity);
        return Request.CreateResponse(HttpStatusCode.OK, result);
    }
    catch (Exception e)
    {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message);
    }
}

错误信息

始终收到415 Unsupported Media Type错误,服务器捕获的请求信息:

RequestMessage = {Method: PUT, RequestUri: 'http://192.168.1.45/OrchardServices/api/Cultivar/Update', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Accept: application/xml
  ContentType: application/xml
  Content-Length: 293
}}

已尝试的操作

  • 将内容类型改为application/octet-stream,问题依旧
  • 移除Web API 2的路由特性,恢复为原Web API 1的PUT("Update")写法,问题依旧

这些方法在旧版Web API 1中运行正常,请问哪里出了问题?


问题根源与修复方案

Web API 2的XML格式化器默认使用DataContractSerializer而非XmlSerializer,这是核心问题:Web API 1默认用XmlSerializer处理XML,而Web API 2切换成了DataContractSerializer,两者序列化的XML结构不兼容,导致服务器无法解析客户端发送的XmlSerializer格式XML,返回415错误。

修复步骤

  1. 配置服务器使用XmlSerializer
    在WebApiConfig.cs的Register方法中添加代码,强制Web API使用XmlSerializer处理XML请求和响应:
config.Formatters.XmlFormatter.UseXmlSerializer = true;
  1. 移除服务器端冗余的手动反序列化代码
    服务器端代码中手动读取流并反序列化的操作完全多余,Web API会通过格式化器自动处理[FromBody]参数。简化后的代码如下:
[Route("Update")]
[HttpPut]
public HttpResponseMessage Put([FromBody] CultivarEntity _Entity)
{
    try
    {
        if (_Entity == null)
        {
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }
        var result = _Accessor.UpdateCultivar(_Entity.cultivar_pk, _Entity);
        return Request.CreateResponse(HttpStatusCode.OK, result);
    }
    catch (Exception e)
    {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e.Message);
    }
}
  1. 额外验证点
  • 确保客户端和服务器端的CultivarEntity类完全一致(包括命名空间、属性名、数据类型)
  • 可以在客户端显式设置请求内容类型,避免全局配置失效:
streamContent.Headers.ContentType = New MediaTypeHeaderValue("application/xml")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:05:37