Yahya Hussein
Yahya Hussein

Reputation: 9121

Override 415 response in ASP.Net Core

In ASP.net Core 2.1, I want to return a Json response along with Status code 415 instead of just 415 returned by default.

To achieve this I am using a resource filter:

public class MediaTypeResouceFilter : Attribute, IResourceFilter
{
    public void OnResourceExecuting(ResourceExecutingContext context)
    {
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        if (context.HttpContext.Response.StatusCode == 415)
        {
            context.Result = new ContentResult() { StatusCode = 415, Content = JsonConvert.SerializeObject(myResponse), ContentType = "application/json" };
        }
    }
}

In debugging, I see that context.Result is being overrided successfully but postman gets only 415 with no Json response.

In case I put:

context.Result = new ContentResult() { StatusCode = 415, Content = JsonConvert.SerializeObject(myResponse), ContentType = "application/json" };

inside OnResourceExecuting instead of OnResourceExecuted, it works as I wish but the thing is that I can't check for status code before executing resource.

Any ideas on why this is happening?

Upvotes: 3

Views: 2238

Answers (3)

guogangj
guogangj

Reputation: 2435

I think using the middleware component is a good choise. This is the Invoke method of the middleware:

public async Task Invoke(HttpContext context) {
    Exception exception = null;
    try {
        await _next(context);
    }
    catch (Exception e) {
        exception = e;
        //try handling exception stuff...
    }

    //try handling 415 code stuff...
    if(context.Response.StatusCode==415){
        var yourJsonObj = new { Blah = "blah..." };
        string result = JsonConvert.SerializeObject(yourJsonObj);
        //context.Response.StatusCode = 200; //You can change the StatusCode here
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsync(result);
    }
}

Upvotes: 2

Khai Nguyen
Khai Nguyen

Reputation: 945

can you try this?

public class MediaTypeResouceFilter : Attribute, IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
        }

        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            if (context.HttpContext.Response.StatusCode == 415)
            {
                var jsonString = JsonConvert.SerializeObject(new { data = "this is custom message" });
                byte[] data = Encoding.UTF8.GetBytes(jsonString);
                context.HttpContext.Response.Body.WriteAsync(data, 0, data.Length);
            }
        }
    }

Then you can get a 415 Status Code and body data is: {"data":"this is custom message"}

Actually OnResourceExecuted fires too late but you can modify the body for your custom message

Upvotes: 4

itminus
itminus

Reputation: 25380

See the workflow by Microsoft :

filter execution workflow

The method of IResourceFilter::OnResourceExecuted(ResourceExecutedContext context) runs after the Result execution. Since the result execution has already finished, you can make no change to result.

Upvotes: 1

Related Questions