Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept the OData "query"

I would like to "intercept"/alter the OData query that's generated when using OData with the Web API.. but I'm not entirely sure of how to "extract" the generated query.. I assume that the OData filter,expands and more some how gets generated to some sort of expression tree or some sort of query.. and if that's the case, then that's the type of query I would like to be able to alter before its sent to the database as an SQL-command.

I have searched the net for some way of extracting the generated expression tree.. but hasn't be able to find sufficient information, so I was sort of hoping that someone here has some more insight of how the whole OData-"framework" works..

Any ideas of where to start?

like image 994
Inx51 Avatar asked Oct 06 '16 12:10

Inx51


People also ask

How does $filter work in OData?

Querying Data Using $filter. You can use filter expressions in OData requests to filter and return only those results that match the expressions specified. You do this by adding the $filter system query option to the end of the OData request.

How do I enable OData query globally?

The EnableQuerySupport method enables query options globally for any controller action that returns an IQueryable type. If you don't want query options enabled for the entire application, you can enable them for specific controller actions by adding the [Queryable] attribute to the action method.

What is $select in OData?

The $select option specifies a subset of properties to include in the response body. For example, to get only the name and price of each product, use the following query: Console Copy. GET http://localhost/odata/Products?$select=Price,Name.


1 Answers

You can alter Odata url before it is executed. Inherit from EnableQueryAttribute class and change url. Following is a real case to change guid string format to hexadecimal string format before it's sent to oracle.

public class EnableQueryForGuid : EnableQueryAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var url = actionContext.Request.RequestUri.OriginalString;

        var newUrl = ModifyUrl(url);

        actionContext.Request.RequestUri = new Uri(newUrl);
        base.OnActionExecuting(actionContext);
    }

    private string ModifyUrl(string url)
    {
        Regex regex = new Regex(@"%27([A-Za-z0-9]{32})%27");
        var res = regex.Matches(url);
        if (res.Count > 0)
        {
            var guidPart = res[0].Value.Remove(0, 3);
            guidPart = guidPart.Remove(guidPart.Length - 3, 3);
            var guidValue = new Guid(BitConverter.ToString((new Guid(guidPart)).ToByteArray()).Replace("-", ""));
            url = url.Replace(res[0].Value, guidValue.ToString());
        }
        return url;
    }
}

then use this new attribute on your controller method:

    [HttpGet]
    [EnableQueryForGuid]
    [ODataRoute("GetSomething")]
    public IHttpActionResult GetSomething()
    {
      ....
    }

original query:

OData/GetSomething?&$filter=MyGuid%20eq%20%272C3C7BC0EC7FA248B0DEE3DAA371EE73%27

altered query:

OData/GetSomething?&$filter=MyGuid%20eq%20e5794d6a-5db1-475a-8c49-0f91a8f53c8a

like image 168
ozanmut Avatar answered Oct 23 '22 09:10

ozanmut