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错误。
修复步骤
- 配置服务器使用XmlSerializer
在WebApiConfig.cs的Register方法中添加代码,强制Web API使用XmlSerializer处理XML请求和响应:
config.Formatters.XmlFormatter.UseXmlSerializer = true;
- 移除服务器端冗余的手动反序列化代码
服务器端代码中手动读取流并反序列化的操作完全多余,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); } }
- 额外验证点
- 确保客户端和服务器端的
CultivarEntity类完全一致(包括命名空间、属性名、数据类型) - 可以在客户端显式设置请求内容类型,避免全局配置失效:
streamContent.Headers.ContentType = New MediaTypeHeaderValue("application/xml")
内容的提问来源于stack exchange,提问作者pjh
相关产品推荐
相关产品推荐

