0

I want to send a HttpResponse if a condition check in a helper method fails so the code after the condition check is never executed.

I am aware of the handy methods like "return Unauthorized()" which can be called in a controller but those can not be used in a helper method. I know that the helper method could return a boolean which is checked in an if clause however a one liner "AssertCondition()" is prefered. Is this possible?

    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        AssertCondition();
        //do other things
        return Ok();
    }

    private void AssertCondition()
    {
        //check some condition 
        if (true == false)
        {
            //condition failed I want to send a http response here
        }
    }
Tom
  • 451
  • 2
  • 12

2 Answers2

1

While you could hook into the request context in your helper method as it looks like it resides in the same controller class as your action, this would not be best practice. What if you wanted to reuse your helper method in other controllers, or elsewhere?

The best way to accomplish what you are describing is by using an Action Filter.

E.g.

public class MyCustomActionFilterAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext context)
  {
    // Check some condition 
    if (true == false)
    {
      // Return a bad request response without executing the action method
      context.Result = new BadRequestResult();
    }
  }
}

Then you could apply this to your action method as follows:

[MyCustomActionFilter]
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
  //do other things
  return Ok();
}
Chris Pickford
  • 7,759
  • 4
  • 41
  • 65
  • Thanks for the tip. Can you give a link how to hook in request/responseContext so I can judge whether it is good or bad for me? – Tom May 28 '19 at 15:34
  • Within the filter you have full access to the request/response context through the `context` parameter. – Chris Pickford May 29 '19 at 12:19
0

No, it's not possible using boilerplate ASP.NET Core. Think of your controller as being just like any other class. It has methods that return results. It wouldn't make sense to be able to do this:

public class DoesSomething
{
    public string GetString(string input)
    {
        HelperMethod();
        return "whatever";
    }

    private void HelperMethod()
    {
       // Somehow cause the calling method, GetString,
       // to return something, circumventing the normal
       // control flow.
    }
}

In effect that's what we would be doing if we returned an ActionResult straight from the helper method. It would be like the private method choosing to return a result on behalf of the method that called it. Because a controller is just like any other class, we can't do that.

The only workaround would be to throw an exception from your helper method. That's not recommended, however, because that means using an exception for control flow. If we want to return a particular status code, there are methods like StatusCode(int) to do that.


The reason I add the qualifier "using boilerplate ASP.NET Core" is because in other versions you could just throw an HttpResponseException from another method, and even within ASP.NET Core people have created custom exceptions and middleware to achieve a similar result. That was removed from ASP.NET Core because it amounts to using exceptions for control flow. See the answer to this question along with its link to another discussion.

Scott Hannen
  • 21,450
  • 3
  • 33
  • 44