2

我坚持使用 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 错误。
我检查了所有可用信息,没有发现它不起作用的原因。
可能是自 MVC5 以来 OData 开始工作而在 MVC4 中它仍然太错误?

4

2 回答 2

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

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

    从您的模型构建器中:

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

    控制器应命名为“ClientController”。

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

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

    但从跟踪来看,您的请求 uri 是:Url=[some_link]/api/ODataGrid 它与上述 odata 路由不匹配,而是与您的第二个路由匹配:

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

    虽然它可以路由和调用“Get”方法,但是“DefaultApi”路由不能序列化“Get”方法返回的结果。所以,响应是“406”。

  3. 您可以执行以下操作以使其正常工作:

    将 ODataGridController 更改为 ClientController;
    删除 MapHttpRoute(...) 调用;
    发送请求为:Url=[some_link]/api/Client

于 2014-12-11T04:00:00.893 回答
0

问题出在这里:

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

我更改了 All no None ,一切都已解决。这也是有问题的:

builder.EntitySet<Client>("Client");
于 2015-01-31T10:53:14.370 回答