我有一个现有的Web API 2服务,需要修改其中一个方法以接受自定义对象作为另一个参数,目前该方法只有一个参数,该参数是来自URL的简单字符串。在将自定义对象作为参数添加后,从.NET Windows应用程序调用服务时,现在出现了415不支持的媒体类型错误。有趣的是,我可以使用JavaScript和jQuery ajax方法成功调用此方法。
Web API 2服务方法如下:
<HttpPost>
<HttpGet>
<Route("{view}")>
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
由于 Paging
对象是可选的,所以该方法允许使用 POST
和 GET
。如果我使用 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有关的问题
到目前为止,无论我尝试什么,都会得到相同的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客户端中我错过了什么?非常感谢任何帮助!
--- 更新 ---
我尝试创建一个全新的Web API服务,以排除现有服务可能存在的任何问题,我创建了一个控制器,其中包含一个以自定义对象为参数的单个方法。然后我尝试从.NET客户端调用该方法,并收到了相同的错误。我还尝试使用WebClient而不是HttpWebRequest,但仍然收到相同的错误。这也是之前对于Web API(Web API 2之前)对我有效的一些东西。
--- 更新 ---
我还尝试创建一个使用Web API 1的新Web应用程序,在我使用POST时,我的复杂对象参数现在为空。我有另一个运行Web API 1的Web服务,并验证我仍然可以成功地调用具有复杂对象的服务。无论我的问题是什么,它似乎都与客户端和服务器之间的JSON传递有关。我已经检查了我发送的JSON并且它是有效的,对象定义也是客户端和服务器之间的完全匹配,因此JSON应该能够被服务器解析。