应用$ select后,WebAPI2 OData异常返回XML

时间:2014-01-14 17:44:51

标签: asp.net-web-api

我有一个应用ODataQueryOptions的控制器并返回非通用IQueryable。这适用于text/html,但在使用application/xml请求text/xml$select时,会抛出此错误:

  

'ObjectContent`1'类型无法序列化响应正文   内容类型'application / xml;字符集= UTF-8' 。

     

类型   “System.Data.Entity.Core.Objects.ObjectQuery 1[[System.Web.Http.OData.Query.Expressions.SelectExpandBinder+SelectSome 1 [[Data2.fn_GetStuff_Result,   Data2,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]],   System.Web.Http.OData,Version = 5.0.0.0,Culture = neutral,   PublicKeyToken = 31bf3856ad364e35]]'带数据合同名称   'ArrayOfSelectExpandBinder.SelectSomeOffn_GetStuff_Resultzy_SQjfTr:http://schemas.datacontract.org/2004/07/System.Web.Http.OData.Query.Expressions'   不是预期的。考虑使用DataContractResolver或添加任何   静态地知道已知类型列表的类型 - 例如,   通过使用KnownTypeAttribute属性或将它们添加到   传递给DataContractSerializer的已知类型列表。

WebApiConfig.Register方法:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(
    new MediaTypeHeaderValue("text/html")); 
modelBuilder.EntitySet<Data2.fn_GetStuff_Result>("Stuff");

这可以在浏览器中正常工作并返回JSON格式的结果。将Accept标头更改为application/xmltext/xml会引发上述异常。如果$select被移除,application/xml将返回application/json结果。

ORM是EF6,类型是从SQL Server的表值函数映射的。

public HttpResponseMessage Get(ODataQueryOptions<Data2.fn_GetStuff_Result> options)

// get Skip and Top from the options

var db = new Data2.MyEntities(); 
var query = db.fn_GetStuff(skip, take).AsQueryable();

// TODO - parse the request uri and strip out $skip and $top as these have already been applied through the server function 
// Applying them again will not return the correct results 
var newUri = new Uri("http://localhost/odata/Stuff()?$select=Id,Name"); 
var newRequest = new HttpRequestMessage(HttpMethod.Get, newUri); 
var newOptions = new ODataQueryOptions<Data2.fn_GetStuff_Result>(
    options.Context, newRequest);

var results = newOptions.ApplyTo(query); 
var response = Request.CreateResponse(HttpStatusCode.OK, results);

return response;

如何根据Accept标头应用$select时返回XML或JSON?

这是堆栈跟踪

<StackTrace>   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
   at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
   at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph)
   at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph)
   at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)
   at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at System.Web.Http.Tracing.ITraceWriterExtensions.&lt;TraceBeginEndAsyncCore&gt;d__33.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at System.Web.Http.WebHost.HttpControllerHandler.&lt;WriteBufferedResponseContentAsync&gt;d__14.MoveNext()</StackTrace></

0 个答案:

没有答案