WCF 数据服务根据Accept:
标头更改其响应 JSON 格式,因此这两个标头提供不同的结果:
Accept: application/json
Accept: application/json; odata=verbose
但是,OData 规范提供了$format=
应该做同样事情的查询参数。WCF 似乎尊重$format=json
参数,但将其视为application/json
接受标头。但我想要详细的 JSON ......
所以我的问题是;的可能值是$format=
多少?有没有办法使用它来指定详细的 JSON?
(我已经知道我可以更改我的代码以使用接受标头,但现有代码正在使用 $format,所以我更喜欢更改它。)
我正在使用预发布的 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
,我会从 WCF 获得 HTTP 500,并在跟踪日志中显示:
<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& item)
at System.ServiceModel.Channels.ReplyChannel.EndTryReceiveRequest(IAsyncResult result, RequestContext& context)
at System.ServiceModel.Dispatcher.ReplyChannelBinder.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
at System.ServiceModel.Dispatcher.ChannelHandler.EndTryReceive(IAsyncResult result, RequestContext& 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.<>c__DisplayClass4.<CallbackGenerator>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& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage9(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage8(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage6(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Dispatch(MessageRpc& 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.<>c__DisplayClass4.<CallbackGenerator>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:
好的,虽然$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 转义的。
惊人的!