使用JSON发布到OData服务时,出现“错误415:不支持的媒体类型”。
解决方案位于此较长文章的底部。
我可以使用JSON进行获取,但是一旦尝试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
请求标题
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 = verbose
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>"}}}
使用DataServiceVersion: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>"}}}
使用WebServiceVerion: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在请求有效负载中使用来表示服务器可以在响应有效负载中使用的媒体类型。
Content-Type
Accept
Content- Type
因此,Content- Type在没有正文的请求中(例如您的GET请求)没有任何意义。当您执行POST请求时,您正在发送消息正文,因此这很Content-Type重要。
如果服务器无法处理Content-Type请求的请求,它将返回415 HTTP错误。(如果服务器不能满足请求Accept标头中的任何媒体类型,它将返回406错误。)
在OData v3中,媒体类型“ application / json”被解释为表示新的JSON格式(“ JSON light”)。如果服务器不支持读取JSON light,则服务器在看到传入的请求是JSON light时将抛出415错误。在有效负载中,您的请求正文是冗长的JSON,而不是JSON light,因此服务器应该能够处理您的请求。但这并不是因为它看到了JSON light内容类型。
您可以通过以下两种方法之一来解决此问题:
DataServiceVersion: 2.0;
(选项2假定您在请求有效负载中未使用任何v3功能。)