Can I send ODataQueryOptions from the body of an Http request?

I am implementing a Web API to support some fairly complex requests that can be run against it, and have encountered a problem with the maximum length of the request URI.

The definition of my Web API method looks like this (using Automapper to do DTO projections):

public IQueryable<ReportModel> Get(ODataQueryOptions<Report> queryOptions)
{
     var query = DbContext.Query<Report>();

     return (queryOptions.ApplyTo(query) as IQueryable<Report>).WithTranslations().Project(MappingEngine).To<ReportModel>().WithTranslations();
}

My query consists of a dynamically generated OData query that includes a potentially large number of Field eq Id filters that are written to the ODataQueryOptions parameter, which is then applied to the IQueryable database context. For instance:

http://example.com/api/Report?$filter=(Field1+eq+1%20or%20Field1+eq+5%20or%20Field1+eq+10%20or%20Field1+eq+15...

, URI . URI 404. , -, 2 (URI 2065 , 2105 Chrome, IE FF).

, , GET POST, URI. , , ODataQueryOptions POST. Web API :

public IQueryable<ReportModel> Post([FromBody] ODataQueryOptions<Report> queryOptions)
{
      var query = DbContext.Query<Report>();

      return (queryOptions.ApplyTo(query) as IQueryable<Report>).WithTranslations().Project(MappingEngine).To<ReportModel>().WithTranslations();
}

, , URI. ODataQueryOptions , - "null". "[FromBody]", URI , URI.

, ( jQuery):

$.ajax({
       url: "/API/Report",
       type: "POST",
       data: ko.toJSON({
           '$filter': 'Field1+eq+1%20or%20Field1+eq+5%20or%20Field1+eq+10%20or%20Field1+eq+15...'
       }),
       dataType: "json",
       processData: false,
       contentType: 'application/json; charset=utf-8',
});

-, , (Post ODataQueryOptions )? , POST? - , ?

+4
1

, post .

. .

public IQueryable<ReportModel> Post([FromBody] string filterRawValue)
{
    var context = new ODataQueryContext(Request.ODataProperties().Model, typeof(Report));
    var filterQueryOption = new FilterQueryOption(filterRawValue, context);
    var query = DbContext.Query<Report>();
    return (filterQueryOption.ApplyTo(query) as IQueryable<Report>).WithTranslations().Project(MappingEngine).To<ReportModel>().WithTranslations();
}
+1

Source: https://habr.com/ru/post/1544197/


All Articles