我有一个应用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/xml
或text/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.<TraceBeginEndAsyncCore>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.<WriteBufferedResponseContentAsync>d__14.MoveNext()</StackTrace></