Search code examples
c#.netasp.net-web-api2odatadynamics-crm-2016

How to accept a query and return an async task?


I am getting the following exception:

Cannot create an EDM model as the action 'Get' on controller 'Accounts' has a return type 'System.Web.Http.IHttpActionResult' that does not implement IEnumerable<T>.

When attempting to query my endpoint:

http://localhost:8267/api/accounts

The AccountsController that is doing the work:

    public async Task<IHttpActionResult> Get(ODataQueryOptions options)
    {
        var query = options.Request.RequestUri.PathAndQuery;
        var client = new HttpClient();
        var crmEndPoint = @"HTTPS://MYCRMORG.COM/API/DATA/V8.1/";
        HttpResponseMessage response = await client.GetAsync(crmEndPoint+query);
        object result;
        if (response.IsSuccessStatusCode)
        {
            result = await response.Content.ReadAsAsync<object>();

            return Ok(result);
        }

        return NotFound();
    }

What am I doing wrong? How do I simply add the PathAndQuery to my crmEndPoint and return the result?


Solution

  • The OData framework provides extra response formatting/querying rules on top of plain Web API.

    Using ODataQueryOptions parameter requires that the action method returns either IQueryable<T> or IEnumerable<T>.

    ODataQueryOptions just helps to parse the incoming OData request url making parameters such as $filter and $sort accessible through properties.

    Your code doesn't need this service because all it does is just redirect the request to the crmEndPoint. So, instead of using options.Request you can access the request object through the Request property of the controller and drop the parameter altogether.

    Here's the code:

    public async Task<IHttpActionResult> Get()
    {
        var query = Request.RequestUri.PathAndQuery;
        var client = new HttpClient();
        var crmEndPoint = @"HTTPS://MYCRMORG.COM/API/DATA/V8.1/";
        HttpResponseMessage response = await client.GetAsync(crmEndPoint + query);
        object result;
        if (response.IsSuccessStatusCode)
        {
            result = await response.Content.ReadAsAsync<object>();
    
            return Ok(result);
        }
    
        return NotFound();
    }