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

'ObjectContent`1'类型无法序列化内容类型'application / xml的响应主体;字符集= UTF-8' . 键入'System.Data.Entity.Core.Objects.ObjectQuery1 [[System.Web.Http.OData.Query.Expressions.SelectExpandBinder SelectSome1 [[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></