SiberianGuy
SiberianGuy

Reputation: 25302

How to specify response type in ASP.NET Core middleware

My controllers return unified RequestResult:

public Task<RequestResult> SomeAction()
{
  ...
  return new RequestResult(RequestResultType.NotFound);
}

public class RequestResult
{
  public RequestResultType Type { get;set; }
  ... //actual data
}

public enum RequestResultType
{
   Success = 1,
   NotFound = 2
}

So basically RequestResult combines actual Action data and error type (if it happened). Now I need to specify Response Type at some point in case if Action returned Error. My best guess here is to use Middleware:

public class ResponseTypeMiddleware
{
  private readonly RequestDelegate next;

  public ResponseTypeMiddleware(RequestDelegate next)
  {
    this.next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    await next(context);

    var response = context.Response.Body; //how to access object?
  }
}

but I can't figure out what to do with it. What I'd perfectly like to do is to check if response is of type RequestResult, then specify ResponseType equal BadRequest. But I don't see how I can do it here as what I have is just a stream. May be I can hijack into pipeline earlier, before result was serialized (Controller?).

P. S. The reason why I don't use Controller.BadRequest directly in Action is that my Action's logic is implemented via CQRS command/query handlers, so I don't have direct access to Controller.

Upvotes: 2

Views: 2863

Answers (1)

Set
Set

Reputation: 49779

As you are going to process controller's action result (MVC), the best way is to use ActionFilter or ResultFilter here, instead of Middleware. Filters in ASP.NET Core are a part of MVC and so know about controllers, actions and so on. Middleware is a more common conception - it is an additional chain in application request-response pipeline.

public class SampleActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // do something before the action executes
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // do something after the action executes

        // get or set controller action result here
        var result = context.Result as RequestResult;
    }
}

Upvotes: 1

Related Questions