Returning css or 404 from a netcoreapp3.1 controller action

Viewed 22

I want to make a controller action to return css.

The browser will only user the CSS if the response type is text/css.

Here is my action.

        [HttpGet("{tenant}/stylesheet")]
        [Produces("text/css")]
        [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
        [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
        public async Task<ActionResult<BrandingDTO>> Stylesheet(string tenant)
        {
            Branding b = dbContext.Branding.SingleOrDefault(z => z.Tenant == tenant);
            if (t == null)
            {
                return NotFound(); // Actually returns 406 unacceptable.
            }

            return Ok(Content($@"
nav.navbar {{
    background-color: {b.PrimaryBrandingColour};             
}}
", "text/css"));
        }

In the not found case I don't need the response to be application/problem+json, but it happens that that's what it is.

I've had to create a custom output formatter.

    /// <summary>
    /// https://learn.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-6.0
    /// </summary>
    internal class CssOutputFormatter : TextOutputFormatter
    {
        public CssOutputFormatter()
        {
            SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/css"));

            SupportedEncodings.Add(Encoding.UTF8);
            SupportedEncodings.Add(Encoding.Unicode);
        }

        protected override bool CanWriteType(Type? type)
        {
            return type == typeof(ContentResult) || type == typeof(string);
        }

        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {

            string buffer = context.Object.ToString();

            ContentResult content = context.Object as ContentResult;
            if(content != null)
            {
                buffer = content.Content;
            }

            await context.HttpContext.Response.WriteAsync(buffer, selectedEncoding);
        }
    }

The problem is that in the not found case the respose is actually 406 not acceptable; I would expect 404 and an empty body of type text/css or a non-empty body of type application/problem+json.

Can this work? Or should I make do with the response being either 202 with text/css else broken?

1 Answers

Hope this will help you.

HttpResponseMessage message=new HttpResponseMessage(HttpStatusCode.OK);
string color = "black";
string content = $"nav.navbar {{background-color: {color};}}";
message.Content=new StringContent(content, System.Text.Encoding.UTF8, "text/plain");
return Ok(message);
Related