使用 JSON 发布到 OData 服务时收到“错误 415:不支持的媒体类型”。
解决方案位于这篇相当长的帖子的底部。
我可以使用 JSON GET,但是一旦我尝试 POST,就会收到此错误。
我还可以使用 XML GET/POST,但我需要使用 json。
我认为这个错误是指我的标头中出现错误,而不是我的请求正文的 json 格式,下面也可能不正确,我尝试了多种导致相同错误的变体。
我一直在尝试使用Fiddler进行调试,结果如下。
JSON 发布
请求
POST http://scdb38:8888/bi.test/applicationdata.svc/Sharks HTTP/1.1
User-Agent: Fiddler
Host: scdb38:8888
Content-Length: 91
Accept: application/json;odata=verbose;
Content-Type: application/json;
{
"d":[
{
"Name":"Great White ",
"Food":"Surfers"
}
]
}
回应
HTTP/1.1 415 Unsupported Media Type
Cache-Control: private
Content-Length: 186
Content-Type: application/json;odata=verbose;charset=utf-8
Server: Microsoft-IIS/7.5
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 16 Oct 2013 06:20:10 GMT
{"error":{"code":"1","message":{"lang":"en-AU","value":"<?xml version=\"1.0\" encoding=\"utf-16\"?><ExceptionInfo><Message>Unsupported media type requested.</Message></ExceptionInfo>"}}}
JSON 获取
请求标头
GET http://scdb38:8888/bi.test/applicationdata.svc/Sharks HTTP/1.1
User-Agent: Fiddler
Host: scdb38:8888
Content-Length: 0
Accept: application/json;odata=verbose;
Content-Type: application/json;
响应头
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 591
Content-Type: application/json;odata=verbose;charset=utf-8
Server: Microsoft-IIS/7.5
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 16 Oct 2013 06:23:41 GMT
{"d":[{"__metadata":{"id":"http://scdb38:8888/BI.Test/ApplicationData.svc/Sharks(1)","uri":"http://scdb38:8888/BI.Test/ApplicationData.svc/Sharks(1)","etag":"W/\"X'00000000000007E4'\"","type":"LightSwitchApplication.Shark"},"Id":1,"RowVersion":"AAAAAAAAB+Q=","Name":"Tiger Shark","Food":"Penguins"},{"__metadata":{"id":"http://scdb38:8888/BI.Test/ApplicationData.svc/Sharks(2)","uri":"http://scdb38:8888/BI.Test/ApplicationData.svc/Sharks(2)","etag":"W/\"X'00000000000007E5'\"","type":"LightSwitchApplication.Shark"},"Id":2,"RowVersion":"AAAAAAAAB+U=","Name":"Grey Nurse","Food":"Lettuce"}]}
我不明白为什么当 GET 工作正常时,POST 不支持媒体类型。我意识到我正在使用 DataServiceVersion: 1.0 并已查找升级,但我使用的是 LightSwitch 2012,并且在引用较新版本而不破坏 LightSwitch 应用程序时遇到了问题。我认为 LightSwitch 2013 使用较新的版本(?),但是升级对我来说带来了新的(非技术)挑战。 我觉得我正在绕圈子,这是我最后的手段,在与同事交谈后,我唯一失败的选择是在数据库上创建一个数据模型并在此基础上创建一个 OData 服务。
---- 更新 ----
此后我尝试了 Jen S 提供的两个修复程序,现在收到错误:400 错误请求。
使用 odata=详细
POST http://scdb38:8888/bi.test/applicationdata.svc/Sharks HTTP/1.1
Accept: application/json;odata=verbose;
Content-Type: application/json;odata=verbose;
Content-Length: 98
Host: scdb38:8888
{
"d":[
{
"Name":"Great White ",
"Food":"Surfers"
}
]
}
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Length: 201
Content-Type: application/json;odata=verbose;charset=utf-8
Server: Microsoft-IIS/7.5
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 16 Oct 2013 23:31:09 GMT
{"error":{"code":"1","message":{"lang":"en-AU","value":"<?xml version=\"1.0\" encoding=\"utf-16\"?><ExceptionInfo><Message>An error occurred while processing this request.</Message></ExceptionInfo>"}}}
使用数据服务版本:1.0
POST http://scdb38:8888/bi.test/applicationdata.svc/Sharks HTTP/1.1
Accept: application/json;odata=verbose;
Content-Type: application/json;
Content-Length: 98
Host: scdb38:8888
DataServiceVersion: 1.0;
{
"d":[
{
"Name":"Great White ",
"Food":"Surfers"
}
]
}
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Length: 201
Content-Type: application/json;odata=verbose;charset=utf-8
Server: Microsoft-IIS/7.5
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 16 Oct 2013 23:31:09 GMT
{"error":{"code":"1","message":{"lang":"en-AU","value":"<?xml version=\"1.0\" encoding=\"utf-16\"?><ExceptionInfo><Message>An error occurred while processing this request.</Message></ExceptionInfo>"}}}
使用WebService版本:2.0
POST http://scdb38:8888/bi.test/applicationdata.svc/Sharks HTTP/1.1
Accept: application/json;odata=verbose;
Content-Type: application/json;
Content-Length: 98
Host: scdb38:8888
DataServiceVersion: 2.0;
{
"d":[
{
"Name":"Great White ",
"Food":"Surfers"
}
]
}
HTTP/1.1 400 Bad Request
Cache-Control: private
Content-Length: 201
Content-Type: application/json;odata=verbose;charset=utf-8
Server: Microsoft-IIS/7.5
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 16 Oct 2013 23:38:23 GMT
{"error":{"code":"1","message":{"lang":"en-AU","value":"<?xml version=\"1.0\" encoding=\"utf-16\"?><ExceptionInfo><Message>An error occurred while processing this request.</Message></ExceptionInfo>"}}}
我正在解决这个问题吗?这只是 json 请求正文结构不正确的问题吗?我尝试了一些变体但没有成功,但是使用 XML 发布是有效的。
----- 解决方案-----
感谢 Jen 的帮助,使用 json 格式发布到 OData 服务对我来说很有效。
POST http://scdb38:8888/bi.test/applicationdata.svc/Sharks HTTP/1.1
Accept: application/json;odata=verbose;
Content-Type: application/json;
Content-Length: 62
Host: scdb38:8888
DataServiceVersion: 1.0;
{
"Name":"Great White ",
"Food":"Surfers"
}
HTTP/1.1 201 Created
Cache-Control: no-cache
Content-Length: 298
Content-Type: application/json;odata=verbose;charset=utf-8
ETag: W/"X'00000000000007E7'"
Location: http://scdb38:8888/BI.Test/ApplicationData.svc/Sharks(4)
Server: Microsoft-IIS/7.5
X-Content-Type-Options: nosniff
DataServiceVersion: 1.0;
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 17 Oct 2013 23:22:12 GMT
{"d":{"__metadata":{"id":"http://scdb38:8888/BI.Test/ApplicationData.svc/Sharks(4)","uri":"http://scdb38:8888/BI.Test/ApplicationData.svc/Sharks(4)","etag":"W/\"X'00000000000007E7'\"","type":"LightSwitchApplication.Shark"},"Id":4,"RowVersion":"AAAAAAAAB+c=","Name":"Great White ","Food":"Surfers"}}
看起来这个问题与
Content-Type
和 Accept
标头之间的差异有关。在 HTTP 中,Content-Type
用于请求和响应负载中,以传达当前负载的媒体类型。 Accept
在请求有效负载中使用,表示服务器可以在响应有效负载中使用哪些媒体类型。
因此,在没有正文的请求(如 GET 请求)中包含
Content-Type
是没有意义的。当您执行 POST 请求时,您正在发送消息正文,因此 Content-Type
确实很重要。
如果服务器无法处理请求的
Content-Type
,它将返回 415 HTTP 错误。 (如果服务器无法满足请求 Accept
标头中的任何媒体类型,它将返回 406 错误。)
在 OData v3 中,媒体类型“application/json”被解释为新的 JSON 格式(“JSON light”)。如果服务器不支持读取 JSON light,那么当它看到传入的请求是 JSON light 时,就会抛出 415 错误。在您的负载中,您的请求正文是详细的 JSON,而不是简单的 JSON,因此服务器应该能够处理您的请求。它只是没有,因为它看到的是 JSON light 内容类型。
您可以通过以下两种方法之一解决此问题:
在请求中包含 DataServiceVersion 标头并将其设置为小于 v3。例如:
DataServiceVersion: 2.0;
(选项 2 假定您在请求负载中未使用任何 v3 功能。)
我遇到了同样的错误,但它与上面的答案无关。在我把头撞在墙上几分钟后,我想起我的网络配置文件被旧代码覆盖了。
问题最终是 Web.config 文件中缺少一些 serviceBehaviors 和服务端点引用。
通常我会发布特定的代码更改,但由于配置文件的复杂性,我认为只是记下这些更改以供人们查看可能会有所帮助。
这并不是大多数情况下的答案,但如果您遇到类似的问题,请记住这一点。需要正确设置 Web 配置才能接受服务端点请求。