ASP.Net Core 2.0 - How to return custom json or xml response from middleware?
Asked Answered
K

1

6

In ASP.Net Core 2.0, I am trying to return a message formatted as json or xml with a status code. I have no problems returning a custom message from a controller, but I don't know how to deal with it in a middleware.

My middleware class looks like this so far:

public class HeaderValidation
{
    private readonly RequestDelegate _next;
    public HeaderValidation(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        // How to return a json or xml formatted custom message with a http status code?

        await _next.Invoke(httpContext);
    }
}
Kettle answered 15/3, 2018 at 16:47 Comment(1)
Please post your question about headers as a separate question on SO.Madid
M
21

To fill response in middleware use httpContext.Response property that returns HttpResponse object for this request. The following code shows how to return 500 response with JSON content:

public async Task Invoke(HttpContext httpContext)
{
    if (<condition>)
    {
       context.Response.StatusCode = 500;  

       context.Response.ContentType = "application/json";

       string jsonString = JsonConvert.SerializeObject(<your DTO class>);

       await context.Response.WriteAsync(jsonString, Encoding.UTF8);

       // to stop futher pipeline execution 
       return;
    }

    await _next.Invoke(httpContext);
}
Madid answered 15/3, 2018 at 18:25 Comment(3)
Thanks for the solution Set, very helpful! Is there any chance to dynamically return json or xml without an if(...) statement? I registered a XmlDataContractSerializerOutputFormatter, but it's only in the scope of services.AddMvc(...)Kettle
@Kettle I added if just to emphasize that middleware could whether return result or invoke next middleware in the pipeline. Regarding dynamic response formatting, I don't know exactly but assume that the best way is to manually choose Response.ContentType based on Accept request HTTP header. For XML format it will be application/xml.Madid
Thanks Set, I understand your if (<condition>) and it's not the if statement that I am referring to. In your code a json is returned. When taking into account xml, it is obvious to add an if statement and work through json and xml depending on the header. However, I prefer less lines of code and avoid this kind of if statement. Is it possible to address the accepted media type json, xml or any other on a more global scale?Kettle

© 2022 - 2024 — McMap. All rights reserved.