2

Я придерживаюсь простейшего сценария OData на MVC4 и .NET4.
Это мой WebApiConfig файл:Получение 406 ошибки кода состояния при использовании MVC4 + OData + Queryable

 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 он все еще был слишком глючным?

+0

Какие OData пространства имен вы используете в WebApiConfig и контроллеров? – martinoss

ответ

0

Проблема здесь:

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

Я не изменил все нет Нет, и все было решено. Это также было проблематично:

builder.EntitySet<Client>("Client"); 
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()); 
    

    но от следа, Ваш запрос Ури: 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

+0

, описанный после '# 2', я сделал (1) изменение маршрута odata на совершенно разные ворота как' routePrefix: "odata" '(2) использовать'/odata/Client', и он отлично работает. 406 может быть возвращен не проблема из odata, а из webapi-маршрута. И, всегда будьте осторожны, что odata является аргументом _sensitive_. – Youngjae

Смежные вопросы