Search code examples
c#asp.net.netasp.net-coreodata

Return entity from bound OData action


I'm trying to return an entity from a bound OData action but I can't find a way that works. The request gets routed correctly but when writing the response, OData complains:

When writing a JSON response, a user model must be specified and the entity set and entity type must be passed to the ODataMessageWriter.CreateODataResourceWriter method or the ODataResourceSerializationInfo must be set on the ODataResource or ODataResourceSet that is being written.

This is how my EdmModel looks like:

builder.EntitySet<EntityDto>("Entities");

builder
 .EntityType<EntityDto>().Collection
 .Action(nameof(EntitiesController.Work))
 .ReturnsFromEntitySet<EntityDto>("Entities");

And this is my handler:

[HttpPost("api/Entities/{key:guid}/Work")]
public async Task<IActionResult> Work([FromODataUri] Guid key, [FromBody] WorkOptions options)
{
    if (!ModelState.IsValid)
    {
        throw new BadRequestException();
    }

    var entity = await _service.DoSomething();
    var dto = _mapper.Map<EntityDto>(entity);
    
    return new OkObjectResult(dto);
}

I tried changing the return type in the EdmBuilder to something generic like IActionResult and that works as long as I'm either not returning anything or an object that is not part of the EdmModel.


Solution

  • The issue was that I tried to bind the action to the collection instead of a single entity but called it with a key parameter. So removing the .Collection from the model solved it for me:

    
        builder
         .EntityType<EntityDto>().Collection
         .EntityType<EntityDto>()
         .Action(nameof(EntitiesController.Work))
         .ReturnsFromEntitySet<EntityDto>("Entities");