当前位置:  开发笔记 > 前端 > 正文

调用Web API 2端点时,HTTP 415不支持的媒体类型错误

如何解决《调用WebAPI2端点时,HTTP415不支持的媒体类型错误》经验,为你挑选了3个好方法。

我有一个现有的Web API 2服务,需要修改其中一个方法以将自定义对象作为另一个参数,目前该方法有一个参数,它是来自URL的简单字符串.将自定义对象添加为参数后,从.NET Windows应用程序调用服务时,我现在收到415不支持的媒体类型错误.有趣的是,我可以使用javascript和jquery ajax方法成功调用此方法.

Web API 2服务方法如下所示:




Public Function GetResultsWithView(view As String, pPaging As Paging) As HttpResponseMessage
   Dim resp As New HttpResponseMessage
   Dim lstrFetchXml As String = String.Empty
   Dim lstrResults As String = String.Empty

   Try
      '... do some work here to generate xml string for the response
      '// write xml results to response
      resp.Content = New StringContent(lstrResults)
      resp.Content.Headers.ContentType.MediaType = "text/xml"
      resp.Headers.Add("Status-Message", "Query executed successfully")
      resp.StatusCode = HttpStatusCode.OK
   Catch ex As Exception
      resp.StatusCode = HttpStatusCode.InternalServerError
      resp.Headers.Add("Status-Message", String.Format("Error while retrieving results from view {0}: {1}", view, ex.Message))
   End Try
   Return resp
End Function

该方法允许两者POST,GET因为该Paging对象是可选的.如果我用一个GET请求调用这个方法就行了.

调用服务的简单.NET客户端代码如下所示:

Dim uri As String = BASE_URI + "fetch/someview"
Dim resp As HttpWebResponse
Dim sr As StreamReader
Dim lstrResponse As String
Dim reqStream As Stream
Dim bytData As Byte()
Dim req As HttpWebRequest = WebRequest.Create(uri)
Dim lstrPagingJSON As String
Dim lPaging As New Paging
Try
   lPaging.Page = 1
   lPaging.Count = 100
   lPaging.PagingCookie = ""
   req.Method = "POST"
   lstrPagingJSON = JsonSerializer(Of Paging)(lPaging)
   bytData = Encoding.UTF8.GetBytes(lstrPagingJSON)
   req.ContentLength = bytData.Length
   reqStream = req.GetRequestStream()
   reqStream.Write(bytData, 0, bytData.Length)
   reqStream.Close()
   req.ContentType = "application/json"

   resp = req.GetResponse()

   sr = New StreamReader(resp.GetResponseStream, Encoding.UTF8)
   lstrResponse = sr.ReadToEnd
   '// do something with the response here
Catch exweb As WebException
   txtOutput.AppendText("Error during request: " + exweb.Message)
Catch ex As Exception
   txtOutput.AppendText(String.Format("General error during request to {0}: {1}", uri, ex.Message))
End Try

.NET客户端在4.5框架上运行,服务在4.5.2框架上.该错误被抛出resp = req.GetResponse().我尝试过的一些事情:

在客户端上,将req.Accept值设置为"application/xml"或"text/xml"

在服务方法中,删除了行`resp.Content.Headers.ContentType.MediaType ="text/xml"

用一些静态JSON替换XML响应内容,试图排除在请求上发送JSON并在响应中获取XML的任何问题

到目前为止,无论我尝试什么,我都会得到相同的415错误响应.

我提到这个从javascript调用时有效,这是我正在运行的ajax调用:

$.ajax({
   headers: {},
   url: "api/fetch/someview",
   type: "POST",
   data: "{Count:100,Page:1,PagingCookie:\"\"}",
   contentType: "application/json; charset=utf-8",
   dataType: "xml",
   success: function (data) {
      alert("call succeeded");
   },
   failure: function (response) {
      alert("call failed");
   }
});

在服务方面,没有什么花哨的路由配置或其他任何东西,它几乎是所有开箱即用的Web API 2.我知道路由工作,呼叫正确路由到方法,他们不会意外地去其他地方,所以我在.NET客户端中缺少什么?任何帮助深表感谢!

--- UPDATE ---
我试图创建一个全新的Web API服务来排除现有服务的任何可能问题,我创建了一个控制器,其中包含一个自定义对象作为参数的方法.然后我尝试从.NET客户端调用它并得到相同的错误.我也尝试使用WebClient而不是HttpWebRequest,但仍然得到相同的错误.这也是以前使用Web API(Web API 2之前)工作的东西.

---更新---
我也尝试使用Web API 1创建一个新的Web应用程序,当我用POST调用它时,我的复杂对象参数现在为null.我有另一个运行Web API 1的Web服务,并验证我仍然可以使用复杂对象成功调用它.无论我的问题是什么,它似乎都是在客户端和服务器之间传递JSON的东西.我已经检查了我发送的JSON并且它是有效的,对象定义也是客户端和服务器之间的完全匹配,因此JSON应该能够被服务器解析.



1> AK3800..:

解决
了这个问题在我的头撞墙几天后,看起来这个问题与客户端和服务器之间的内容类型协商有关.我深入研究了使用Fiddler检查来自客户端应用程序的请求详细信息,这里是fiddler捕获的原始请求的屏幕截图:

Fiddler从客户端应用程序捕获http请求

显然缺少的是Content-Type标题,即使我在原始帖子的代码示例中设置它也是如此.我觉得很奇怪,Content-Type即使我正在设置它也没有通过,所以我再看看我的其他(工作)代码调用不同的Web API服务,唯一的区别是我碰巧在req.ContentType之前设置属性在这种情况下写信给请求正文.我对这个新代码进行了更改,并且做到了,Content-Type现在已经出现了,我从Web服务获得了预期的成功响应.我的.NET客户端的新代码现在看起来像这样:

req.Method = "POST"
req.ContentType = "application/json"
lstrPagingJSON = JsonSerializer(Of Paging)(lPaging)
bytData = Encoding.UTF8.GetBytes(lstrPagingJSON)
req.ContentLength = bytData.Length
reqStream = req.GetRequestStream()
reqStream.Write(bytData, 0, bytData.Length)
reqStream.Close()
'// Content-Type was being set here, causing the problem
'req.ContentType = "application/json"

就是这样,在ContentType写入请求主体之前需要设置属性

我相信这种行为是因为一旦将内容写入正文,它就被流式传输到被调用的服务端点,需要在此之前设置与请求相关的任何其他属性.如果我错了或者需要更多细节,请纠正我.



2> James Wierzb..:

在调用我的web api端点并解决它时,我遇到了这个问题.

在我的情况下,这是客户端编码正文内容的方式的问题.我没有指定编码或媒体类型.指定它们解决了它.

未指定编码类型,导致415错误:

var content = new StringContent(postData);
httpClient.PostAsync(uri, content);

指定编码和媒体类型,成功:

var content = new StringContent(postData, Encoding.UTF8, "application/json");
httpClient.PostAsync(uri, content);


魔术字符串"application/json"在.NET Core库中的任何位置都可用作常量吗?

3> 小智..:

我也遇到了这个错误。

我添加到标题Content-Typeapplication/json。更改之后,我的提交成功了!


带有注释的答案需要编辑,不建议使用。
推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有