使用MVC4 + OData + Queryable时接收406状态码错误

时间:2014-11-11 20:08:57

标签: asp.net-mvc-4 asp.net-web-api odata iqueryable http-status-code-406

我坚持使用MVC4和.NET4上最简单的OData方案 这是我的WebApiConfig文件:

        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Client>("Client");

        config.Routes.MapODataRoute(
          routeName: "odataapi",
          routePrefix: "api",
          model: builder.GetEdmModel()
        );
        config.EnableQuerySupport();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.EnableQuerySupport();
        config.EnableSystemDiagnosticsTracing();
        config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling =
              Newtonsoft.Json.PreserveReferencesHandling.All;

这是我的控制者:

public class ODataGridController : ODataController
{
    DevEntities dbcontext = EFRepository.Create<DevEntities>(); 

    [HttpGet]
    [Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IQueryable<Client> Get()
    {
        var model = dbcontext.Client.AsQueryable();
        return model;
    }
}

这是我在VisualStudio中的跟踪数据:

iisexpress.exe Information: 0 : Request, Method=GET, Url=[some_link]/api/ODataGrid, Message='[some_link]/api/ODataGrid'
iisexpress.exe Information: 0 : Message='Will use same 'JsonMediaTypeFormatter' formatter', Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'XmlMediaTypeFormatter' formatter', Operation=XmlMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'FormUrlEncodedMediaTypeFormatter' formatter', Operation=FormUrlEncodedMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'JQueryMvcFormUrlEncodedFormatter' formatter', Operation=JQueryMvcFormUrlEncodedFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'JsonMediaTypeFormatter' formatter', Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'XmlMediaTypeFormatter' formatter', Operation=XmlMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'FormUrlEncodedMediaTypeFormatter' formatter', Operation=FormUrlEncodedMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'JQueryMvcFormUrlEncodedFormatter' formatter', Operation=JQueryMvcFormUrlEncodedFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='ODataGrid', Operation=DefaultHttpControllerSelector.SelectController
iisexpress.exe Information: 0 : Message='Will use new 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='MvcApplication6.Services.ODataGridController', Operation=DefaultHttpControllerActivator.Create
iisexpress.exe Information: 0 : Message='MvcApplication6.Services.ODataGridController', Operation=HttpControllerDescriptor.CreateController
iisexpress.exe Information: 0 : Message='Selected action 'Get()'', Operation=ApiControllerActionSelector.SelectAction
iisexpress.exe Information: 0 : Message='Selected action 'Get()'', Operation=ODataActionSelector.SelectAction
iisexpress.exe Information: 0 : Message='Selected action 'Get()'', Operation=ODataActionSelector.SelectAction
iisexpress.exe Information: 0 : Operation=HttpActionBinding.ExecuteBindingAsync
iisexpress.exe Information: 0 : Operation=HttpActionBindingTracer.ExecuteBindingAsync
iisexpress.exe Information: 0 : Operation=HttpActionBindingTracer.ExecuteBindingAsync
iisexpress.exe Information: 0 : Operation=QueryableAttribute.ActionExecuting
'iisexpress.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\System.Data.OracleClient\v4.0_4.0.0.0__b77a5c561934e089\System.Data.OracleClient.dll', Symbols loaded.
'iisexpress.exe' (Managed (v4.0.30319)): Loaded 'EntityFrameworkDynamicProxies-MvcApplication6'
iisexpress.exe Information: 0 : Message='Action returned 'SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[status] AS [status], 
    [Extent1].[firstname] AS [firstname], 
    [Extent1].[lastname] AS [lastname], 
    [Extent1].[ssn] AS [ssn], 
    [Extent1].[addr_city] AS [addr_city], 
    [Extent1].[addr_street] AS [addr_street], 
    [Extent1].[addr_home] AS [addr_home], 
    [Extent1].[phone_cell] AS [phone_cell], 
    [Extent1].[phone_home] AS [phone_home], 
    [Extent1].[phone_spose] AS [phone_spose], 
    [Extent1].[work_name] AS [work_name], 
    [Extent1].[work_phone] AS [work_phone], 
    [Extent1].[fax] AS [fax], 
    [Extent1].[email] AS [email], 
    [Extent1].[facebook] AS [facebook], 
    [Extent1].[remark] AS [remark], 
    [Extent1].[office_id] AS [office_id], 
    [Extent1].[picture] AS [picture]
    FROM [dbo].[Client] AS [Extent1]'', Operation=HttpActionDescriptorTracer.ExecuteAsync
iisexpress.exe Information: 0 : Message='Will use new 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use new 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use new 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use new 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use new 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use new 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'FormUrlEncodedMediaTypeFormatter' formatter', Operation=FormUrlEncodedMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'JQueryMvcFormUrlEncodedFormatter' formatter', Operation=JQueryMvcFormUrlEncodedFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'ODataMediaTypeFormatter' formatter', Operation=ODataMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'FormUrlEncodedMediaTypeFormatter' formatter', Operation=FormUrlEncodedMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Will use same 'JQueryMvcFormUrlEncodedFormatter' formatter', Operation=JQueryMvcFormUrlEncodedFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Selected formatter='none', content-type='none'', Operation=DefaultContentNegotiator.Negotiate
iisexpress.exe Information: 0 : Message='Selected formatter='none', content-type='none'', Operation=PerRequestContentNegotiator.Negotiate
iisexpress.exe Information: 0 : Message='Selected formatter='none', content-type='none'', Operation=PerRequestContentNegotiator.Negotiate
iisexpress.exe Information: 0 : Operation=ApiControllerActionInvoker.InvokeActionAsync, Status=406 (NotAcceptable)
iisexpress.exe Information: 0 : Operation=QueryableAttribute.ActionExecuted, Status=406 (NotAcceptable)
iisexpress.exe Information: 0 : Operation=ODataGridController.ExecuteAsync, Status=406 (NotAcceptable)
iisexpress.exe Information: 0 : Response, Status=406 (NotAcceptable), Method=GET, Url=[some_link]/api/ODataGrid, Message='Content-type='none', content-length=unknown'
iisexpress.exe Information: 0 : Operation=ODataGridController.Dispose

dbcontext是常规的EF6上下文 当我执行请求时,我收到406错误 我检查了所有可用的信息,看不出它为什么不起作用 可能是OData从MVC5开始工作,而在MVC4中它仍然是太过马车了?

2 个答案:

答案 0 :(得分:1)

  1. 在Web API OData中,约定控制器类的名称遵循模板:

    public class {EntitySetName}Controller : ODataController
    {
        // ...
    }
    

    从您的模型构建器中:

    builder.EntitySet<Client>("Client");
    

    控制器应命名为&#34; ClientController&#34;。

  2. 您将Web API OData路由添加为

    config.Routes.MapODataRoute(
          routeName: "odataapi",
          routePrefix: "api",
          model: builder.GetEdmModel());
    

    但是从跟踪中,您的请求是:Url=[some_link]/api/ODataGrid 它与上述odata路线不匹配,而是匹配您的第二条路线:

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional });
    

    虽然它可以路由和调用&#34; Get&#34;方法,但&#34; DefaultApi&#34; route不能序列化从&#34; Get&#34;返回的结果。方法。因此,响应是&#34; 406&#34;。

  3. 您可以执行以下操作:

    将ODataGridController更改为ClientController;
    删除MapHttpRoute(...)调用;
    发送请求为:网址= [some_link] / api /客户端

答案 1 :(得分:0)

问题在于:

config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;

我改变了所有没有,一切都解决了。 这也有问题:

builder.EntitySet<Client>("Client");