Alex Herman
Alex Herman

Reputation: 2838

return DTO from WebAPI controller

Haven't managed to find any posts covering this aspect unfortunately.

I created a WebAPI app (ASP.NET Core 2.1) and utilize NSwag which I use to auto-generate typescript service proxies.

I've seen code examples where JsonResult & ActionResult is returned by controller action.

DTOs normally belong in Service Layer, so I wonder if it's okay to use them as controller action output.

I wonder if it is correct to return DTO from controller action.

Controller:

[Route("api/[controller]/[action]")]
[Authorize]
public class EntryController : ControllerBase
{
    private readonly IEntryService _entryService;

    public EntryController(
        IEntryService entryService
        )
    {
        _entryService = entryService;
    }

    public async Task<List<EntryDto>> GetMany(long id)
    {
        var result = await _entryService.GetMany(id);
        return result;
    }
}

Service:

public class EntryService : BaseService, IEntryService
{
    private readonly IEntryHighPerformanceService _entryHighPerformanceService;

    public EntryService(
        AppDbContext context,
        IEntryHighPerformanceService entryHighPerformanceService,
        SessionProvider sessionProvider
        ) : base(
              context,
              sessionProvider
              )
    {
        _entryHighPerformanceService = entryHighPerformanceService;
    }

    public async Task<List<EntryDto>> GetMany(long id)
    {
        var dtos = _entryHighPerformanceService.GetByVocabularyId(id);
        return await Task.FromResult(dtos);
    }
}

Upvotes: 2

Views: 3542

Answers (1)

Nkosi
Nkosi

Reputation: 247153

Reference Controller action return types in ASP.NET Core Web API

ActionResult<T> type

ASP.NET Core 2.1 introduces the ActionResult<T> return type for Web API controller actions. It enables you to return a type deriving from ActionResult or return a specific type. ActionResult offers the following benefits over the IActionResult type:

  • The [ProducesResponseType] attribute's Type property can be excluded. For example, [ProducesResponseType(200, Type = typeof(Product))] is simplified to [ProducesResponseType(200)]. The action's expected return type is instead inferred from the T in ActionResult<T>.
  • Implicit cast operators support the conversion of both T and ActionResult to ActionResult<T>. T converts to ObjectResult, which means return new ObjectResult(T); is simplified to return T;.

Taking your controller for example

[HttpGet]
public async Task<ActionResult<List<EntryDto>>> GetMany(long id) {
    //lets say we wanted to validate id
    if(id < 1) {
        return BadRequest("id must be greater than zero (0)");
    }

    var result = await _entryService.GetMany(id);
    if(result == null || result.Count == 0) {
        return NotFound(); // returns proper response code instead of null
    }
    return result;
}

Upvotes: 2

Related Questions