6

From this source: http://www.tutorialsteacher.com/webapi/action-method-return-type-in-web-api I got, that Action in Web API can return:

  1. void
  2. Primitive type or Complex type
  3. HttpResponseMessage
  4. IHttpActionResult

I know what each of this options does, but I am curious whether there is some best practise, for example always use IHttpActionResult as return type, because it is a superset of all other options.

MacakM
  • 1,804
  • 3
  • 23
  • 46

4 Answers4

2

I use asp.net core but principle is the same. Also, not saying this is the best way, but for me this is the setup that works pretty nice.

I always use IActionResult as its most flexible for me. I can then have action methods completely unaware of DTOs that my services (which action methods call) return. All i do is, more or less, something like this:

[CustomExceptionsFilter]
[CustomValidateModelFilter]
[Authorize(Roles="whatever")]
public IActionResult ActionMethod(params){
  return Ok(this._myService.whatever());
}

This way, if you change DTO that your service returns (which happens alot, especially in early development phases), i don' thave to touch my controller at all.

Also, i have pretty much unified way of returning things where my custom exception error filter catches all service layer custom exceptions like validation exception, operation exception, etc...

[UPDATE]

in filters you don't actually return in a traditional sense. You rather set your context.result (which is of type IActionResult). So, lets say my service throws my custom MyServiceOperationException("You cannot do that") exception.

What i do in my exception filter is:

public override void OnException(ExceptionContext context)
    {
      if (context.Exception is MyServiceOperationException)
      {
        context.Result = new BadRequestObjectResult(new MyErrorResult(){ 
          Message = context.Exception.Message,
          Code=context.Exception.MyErrorCode }
          );
      }
}
dee zg
  • 13,793
  • 10
  • 42
  • 82
  • So in your filters you also return `IActionResult`? I thought that I can return there only the `HttpRequestMessage` – MacakM Oct 14 '17 at 18:08
  • Thank you, however in .NET there is not `context.Result` but only `context.Response` which is `HttpRequestMessage` – MacakM Oct 14 '17 at 18:21
  • right, if you use first version of `asp mvc web-api` then you have to set `httpresponsemessage` but its still the same logic. – dee zg Oct 14 '17 at 18:31
  • I use ASP.NET Web API 2, I think the difference is only between ASP.NET and ASP.NET Core – MacakM Oct 14 '17 at 18:39
2

Option 1: Returning void, Primitive type, Complex type

Pros:

  1. Clear from the signature what is the return type.
  2. Unit testing is easier.

Cons:

  1. Not flexible if you want to return a status code if something goes wrong.

Option 2: Returning HttpResponseMessage

Pros:

  1. Flexible to return all items in option 1
  2. Can also return status codes if needed.

Cons:

  1. Not clear from the signature what the return type is.
  2. Unit testing is harder because you have to unwrap it. (not that harder but harder than option 1)
  3. Concerns itself with lower level http status codes and message construction.

Option 3: Returning IHttpActionResult

Web API 2.0 introduced this.

Pros:

  1. All pros of option 2
  2. It does not concern itself with lower level http status codes and message construction.

Cons:

  1. All cons from Option 2 except con 3.

Conclusion

As you can see each option has pros and cons. For me the pros of each option outweigh the cons. My choice is: Option 3. But it is not written in stone.

CodingYoshi
  • 25,467
  • 4
  • 62
  • 64
  • In https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results is stated, that `IHttpActionResult` simplifies unit testing because it is a Factory – MacakM Oct 14 '17 at 18:28
  • @MacakM yes they say that but I do not see how. Then when you go to [the link](https://learn.microsoft.com/en-us/aspnet/web-api/overview/testing-and-debugging/unit-testing-controllers-in-web-api) in the unit test which returns `IHTTPActionResult`, you can see they are casting. So yes easier than `HttpResponseMessage` but not easier than option 1. Thus it is still a con. – CodingYoshi Oct 14 '17 at 18:34
1

IActionRsult is very flexible in the way that you can return just responses, Json data or views.

Not only for a WepAPI, but for any application, it is better to return the most strict type you can get away with, but again, if a particular action in your controller might return different stuff, IActionResult would be the way to go.

TheXDS
  • 88
  • 9
1

The advantage of IHttpActionResult, and why I always use it, is that it guides you to think about your actions as generating HTTP responses. ASP.NET has a long history of obfuscating simple parts of widely understood protocols, and this is a step in the right direction in my opinion!

Nat Wallbank
  • 1,377
  • 12
  • 12