2017-07-03 42 views
4

我有一個Web API項目,在沒有OData支持的情況下使用了好幾年,只有標準的URL參數。支持現有Web API中的ODataQueryOptions

我現在希望爲此API添加OData支持,但由於API不是建立在可查詢模型上,因此我們打算接收ODataQueryOptions<T>對象並將其傳遞給存儲庫。

我所能找到的關於支持OData的任何內容都假定我有可查詢的模型或過於簡單化,並簡單地告訴我如何理解ODataQueryOptions對象。因此我無法獲得一個簡單的方法並運行。

這是我目前有。

[Route("test")] 
[HttpGet] 
[EnableQuery] 
public IHttpActionResult Test(ODataQueryOptions<TestOptions> options) 
{ 
    var settings = new ODataValidationSettings { 
      AllowedFunctions = AllowedFunctions.None, 
      AllowedLogicalOperators = AllowedLogicalOperators.Equal, 
      AllowedArithmeticOperators = AllowedArithmeticOperators.None, 
      AllowedQueryOptions = AllowedQueryOptions.Filter 
     }; 
    try 
    { 
     options.Validate(settings); 
    } 
    catch (ODataException exception) 
    { 
     return BadRequest(exception.Message); 
    } 

    var binaryOperator = options.Filter?.FilterClause?.Expression as BinaryOperatorNode; 
    if (binaryOperator != null) 
    { 
     var property = binaryOperator.Left as SingleValuePropertyAccessNode ?? binaryOperator.Right as SingleValuePropertyAccessNode; 
     var constant = binaryOperator.Left as ConstantNode ?? binaryOperator.Right as ConstantNode; 

     if (property?.Property != null && constant?.Value != null) 
     { 
      ; 
     } 
    } 

    return Ok(); 
} 

TestOptions類(在ODataQueryOptions<TestOptions> PARAM)目前是一個空類:

public class TestOptions 
{ 
} 

我還添加了

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     // existing code 

     config.AddODataQueryFilter(); 
    } 
} 

然而,在從REST API調用此客戶...

{
「消息」:「發生錯誤」,
「ExceptionMessage」:「未註冊非OData HTTP路由。」,
「ExceptionType」: 「System.InvalidOperationException」,
「堆棧跟蹤」: 「......」
}

有什麼我錯過了我本來以爲我可能要註冊?在global.asax中啓用OData的方法或類似方法,但例外意味着問題是使用非OData方法,但所有其他方法仍按預期方式返回(,沒有任何OData參與)

+0

我認爲這裏的錯誤信息有些誤導,你需要註冊OData路由。按照這裏的說明應該讓你開始:https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an -odata-v4-endpoint – TomDoesCode

+0

該示例基於EF模型,就像我在OP中所說的那樣,我沒有基礎模型。該示例向OData端點註冊了其模型的特定詳細信息:https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint#configure-the-odata-endpoint – awj

+0

好的,你仍然需要建立一個模型,即使它不是通過實體框架。您的模型是否會在編譯時定義? I.E會暴露的類型和屬性是否改變? – TomDoesCode

回答

3

實際上,如果沒有EntityDate或任何其他模型設置,此功能可以很好地工作。您只需要一個List<Poco.Language>,您可以使用.AsQueryable()進行轉換並關閉。

[Route(""), HttpGet] 
public IHttpActionResult Get(ODataQueryOptions<Poco.Language> queryOptions) 
{   
    return Ok(queryOptions.ApplyTo(_repository.GetAll().AsQueryable())); 
} 

上述控制器可與所有類型的OData的查詢選項,正常的路線,並在WebApiConfig沒有設置調用。

Poco.Language只是一個普通的C#POCO類。

+1

正是我在找的東西! – awj

+0

如果您仍然遇到問題,請根據OData庫版本,在您的webapi配置中添加'config.EnableDependencyInjection();'。請參閱https://github.com/Data/WebApi/issues/816 – Chandermani

0

您是否將此添加到您的啓動?

public void Configuration(IAppBuilder appBuilder) 
     { 
      // Set up server configuration 
      var config = new HttpConfiguration(); 
      config.Routes.MapODataRoute(routeName: "OData", routePrefix: "odata", model: GetEdmModel()); 
      appBuilder.UseWebApi(config); 
     } 

     private IEdmModel GetEdmModel() 
     { 
      var modelBuilder = new ODataConventionModelBuilder(); 
      modelBuilder.EntitySet<Customer>("customer"); 
      modelBuilder.EntitySet<Order>("order"); 
      modelBuilder.EntitySet<Customer>("response"); 
      return modelBuilder.GetEdmModel(); 
     } 

我正在嘗試做同樣的事情,但使用.Net Core Web Api。我從https://github.com/OData/ODataSamples下載了樣品,他有一個工作項目,完全符合我們的要求。看看ODataQueryableSample.csproj。它不使用EntityFramework,只是在內存中創建一個列表。

此外,我不認爲你需要[EnableQuery]屬性和ODataQueryOptions參數 - 該示例提供了一個示例,並沒有一起使用它們。我還沒有看到它在我的PC上工作,所以我相信它只是一個配置(例如,我的啓動使用IApplicationBuilder而不是IAppBuilder)。您也可以嘗試從瀏覽器中獲取更好的異常消息。