Search code examples
odataasp.net-core-webapi

How to implement OData Core with async await?


I'm implementing OData for a personal project. At this moment I have this code

    [HttpPost]
    [ODataRoute("Classes", RouteName = "PostClass")]
    public IActionResult PostClass([FromBody] Class @class)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        @class.Id = Guid.NewGuid();
        _context.Classes.Add(@class);
        _context.SaveChangesAsync();

        //return CreatedAtAction("GetClass", new { id = @class.Id }, @class);
        return Created(@class);
    }

It is working fine but I would like if I can improve it with sync await system like this:

    [HttpPost]
    [ODataRoute("Classes", RouteName = "PostClass")]
    public async Task<ActionResult<Class>> PostClass([FromBody] Class @class)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        @class.Id = Guid.NewGuid();
        _context.Classes.Add(@class);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetClass", new { id = @class.Id }, @class);
        //return Created(@class);
    }

When I do this second solution the code build but I get a 500 Internal Server Error.

With

    [HttpPost]
    [ODataRoute("Classes", RouteName = "PostClass")]
    public async Task<ActionResult<Class>> PostClass([FromBody] Class @class)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        @class.Id = Guid.NewGuid();
        _context.Classes.Add(@class);
        await _context.SaveChangesAsync();

        //return CreatedAtAction("GetClass", new { id = @class.Id }, @class);
        return Created(@class);
    }

The code cannot build because

Severity Code Description Project File Line Suppression State Error CS0029 Cannot implicitly convert type 'Microsoft.AspNet.OData.Results.CreatedODataResult' to 'Microsoft.AspNetCore.Mvc.ActionResult' Oyg.Api C:\Users\Public\Projects\oyg-server\Api\Controllers\ClassesController.cs 96 Active

Ok clear but then what method should I use in place of Created() ?


Solution

  • That's because the type CreatedODataResult returned by the Created<TEntity>(entity) method is not a subclass of ActionResult, but a class that implements the IActionResult interface:

    public class CreatedODataResult<T> : IActionResult
    {
        // ...
    }
    

    To fix your code, simply change the Task<ActionResult<Class>> to be Task<IActionResult> :

        [HttpPost]
        [ODataRoute("Classes", RouteName = "PostClass")]
        public async Task<IActionResult> PostClass([FromBody] Class @class)
        {
            // ...
            return Created(@class);
        }