2012-11-01 114 views
0

WCF數據服務的變化基礎上,Accept:頭的響應JSON格式,所以這2頭提供不同的結果:

Accept: application/json 
Accept: application/json; odata=verbose 

然而,OData的規範提供了$format=查詢參數應該做同樣的事情。 WCF似乎尊重$format=json參數,但將其視爲application/json接受標頭。但我想詳細的JSON ...

所以我的問題是, $format=有什麼可能的值?有沒有一種方法來指定使用它的詳細JSON?

(我已經知道我可以改變我的代碼使用接受頭,但現有的代碼使用$格式,所以我更願意改變這種代替。)

我使用的是預發佈WCF數據服務,V5.1.0-RC2


編輯:

我的要求是這樣的:

網址:

http://localhost:52116/Services/MusicStore.svc/Albums?$format=json&%24inlinecount=allpages&%24filter=substringof('the'%2Ctolower(Title)) 

請求報頭:

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8 
DataServiceVersion: 3.0 
Host: localhost:52116 
MaxDataServiceVersion: 3.0 
MinDataServiceVersion: 3.0 
Proxy-Connection: keep-alive 
Referer: http://localhost:52116/ 
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 
X-Requested-With: XMLHttpRequest 

這將返回有效的JSON(非詳細)。

但是,如果我嘗試$format=jsonverbose然後我得到一個HTTP 500從WCF,這個跟蹤日誌中:

<Exception> 
<ExceptionType>System.ServiceModel.CommunicationObjectAbortedException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType> 
<Message>The communication object, System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel, cannot be used for communication because it has been Aborted.</Message> 
<StackTrace> 
at System.ServiceModel.Channels.CommunicationObject.ThrowIfAborted() 
at System.ServiceModel.Channels.InputQueueChannel`1.EndDequeue(IAsyncResult result, TDisposable&amp; item) 
at System.ServiceModel.Channels.ReplyChannel.EndTryReceiveRequest(IAsyncResult result, RequestContext&amp; context) 
at System.ServiceModel.Dispatcher.ReplyChannelBinder.EndTryReceive(IAsyncResult result, RequestContext&amp; requestContext) 
at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.EndTryReceive(IAsyncResult result, RequestContext&amp; requestContext) 
at System.ServiceModel.Dispatcher.ChannelHandler.EndTryReceive(IAsyncResult result, RequestContext&amp; requestContext) 
at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result) 
at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result) 
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) 
at System.ServiceModel.Diagnostics.TraceUtility.&lt;&gt;c__DisplayClass4.&lt;CallbackGenerator&gt;b__2(AsyncCallback callback, IAsyncResult result) 
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) 
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously, Exception exception) 
at System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item) 
at System.Runtime.InputQueue`1.Shutdown(Func`1 pendingExceptionGenerator) 
at System.ServiceModel.Channels.InputQueueChannel`1.OnClosing() 
at System.ServiceModel.Channels.CommunicationObject.Abort() 
at System.ServiceModel.Dispatcher.ReplyChannelBinder.Abort() 
at System.ServiceModel.Channels.ServiceChannel.OnAbort() 
at System.ServiceModel.Channels.CommunicationObject.Abort() 
at System.Data.Services.DelegateBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer) 
at System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer) 
at System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer) 
at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer) 
at System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer) 
at System.ServiceModel.Channels.Message.WriteMessage(XmlWriter writer) 
at System.ServiceModel.Channels.ByteStreamMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset) 
at System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset) 
at System.ServiceModel.Channels.MessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager) 
at System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message) 
at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout) 
at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.SendReplyCore(Message message, TimeSpan timeout) 
at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.SendReply(Message message, TimeSpan timeout) 
at System.ServiceModel.Channels.HttpRequestContext.OnReply(Message message, TimeSpan timeout) 
at System.ServiceModel.Activation.HostedHttpContext.OnReply(Message message, TimeSpan timeout) 
at System.ServiceModel.Channels.RequestContextBase.Reply(Message message, TimeSpan timeout) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage9(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage8(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage6(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc) 
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) 
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Dispatch(MessageRpc&amp; rpc, Boolean isOperationContextSet) 
at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext) 
at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext) 
at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result) 
at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result) 
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) 
at System.ServiceModel.Diagnostics.TraceUtility.&lt;&gt;c__DisplayClass4.&lt;CallbackGenerator&gt;b__2(AsyncCallback callback, IAsyncResult result) 
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously) 
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously, Exception exception) 
at System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item) 
at System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread) 
at System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread) 
at System.ServiceModel.Channels.InputQueueChannel`1.EnqueueAndDispatch(TDisposable item, Action dequeuedCallback, Boolean canDispatchOnThisThread) 
at System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread) 
at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.CompleteParseAndEnqueue(IAsyncResult result) 
at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.HandleParseIncomingMessage(IAsyncResult result) 
at System.Runtime.AsyncResult.SyncContinue(IAsyncResult result) 
at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult..ctor(ReplyChannelAcceptor acceptor, Action dequeuedCallback, HttpPipeline pipeline, AsyncCallback callback, Object state) 
at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action dequeuedCallback, AsyncCallback callback, Object state) 
at System.ServiceModel.Channels.HttpRequestContext.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action acceptorCallback, AsyncCallback callback, Object state) 
at System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1.ProcessHttpContextAsync() 
at System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1..ctor(HttpRequestContext requestContext, Action acceptorCallback, HttpChannelListener`1 listener, AsyncCallback callback, Object state) 
at System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext context, Action acceptorCallback, AsyncCallback callback, Object state) 
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result) 
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest() 
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest() 
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state) 
at System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state) 
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state) 
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) 
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped) 
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) 
</StackTrace> 
<ExceptionString>System.ServiceModel.CommunicationObjectAbortedException: The communication object, System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel, cannot be used for communication because it has been Aborted.</ExceptionString> 

編輯2:

OK,所以,當$format=jsonverbose似乎到HTTP500,這個URL確實給了我想要的東西:

http://localhost:52116/Services/MusicStore.svc/Albums?$format=application%2fjson%3bodata%3dverbose&%24inlinecount=allpages&%24filter=substringof('the'%2Ctolower(Title)) 

所以基本上這是$format=application/json;odata=verbose URL轉義。

太棒了!

回答

5

在5.1.0的$格式標頭將接受以下值:

  • JSON
  • verbosejson
  • 原子

任何其他值將嘗試被解釋爲一個文字Accept頭的值,例如$ format = application/json; odata = verbose是$ format = jsonverbose的同義詞。

我通常使用以下方法:

  • $格式= JSON
  • $格式= verbosejson
  • $格式=應用/ JSON;的OData = fullmetadata
+0

是那些僅有的兩個odata'param可能的值? – jere

+0

也只是推特你馬克,但如果我翻轉到「jsonverbose」,我得到一個HTTP 500瓦特/這在跟蹤日誌中:'System.ServiceModel.CommunicationObjectAbortedException,System.ServiceModel,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'消息:'通信對象System.ServiceModel.Channels.TransportReplyChannelAcceptor + TransportReplyChannel不能用於通信,因爲它已被中止。「我將在上面的原始文章中添加更多細節... – CodingWithSpike

+0

您的最後一行有人告訴我試圖在查詢字符串中使用'$ format = application/json; odata = verbose',這可以工作。謝謝你的幫助! – CodingWithSpike