Carter icon indicating copy to clipboard operation
Carter copied to clipboard

IResponseNegotiator not terminating response and falling through to ExecuteReturnAsync.WriteJsonResponseAsync

Open toddsmith-adsk opened this issue 11 months ago • 8 comments

I found that the default middleware in .NET 9 Minimal API is executing the following code below. When using IResponseNegotiator if I don't return an IResult object from my method it falls through to the WriteJsonResponseAsync call and then throws an exception about headers being read-only.

https://github.com/dotnet/aspnetcore/blob/1770dcf4e81872395cc4d3b3b3efbaef91f8020a/src/Shared/RouteHandlers/ExecuteHandlerHelper.cs#L27

   public static Task ExecuteReturnAsync(object obj, HttpContext httpContext, JsonTypeInfo<object> jsonTypeInfo)
    {
        // Terminal built ins
        if (obj is IResult result)
        {
            return result.ExecuteAsync(httpContext);
        }
        else if (obj is string stringValue)
        {
            SetPlaintextContentType(httpContext);
            return httpContext.Response.WriteAsync(stringValue);
        }
        else
        {
            // Otherwise, we JSON serialize when we reach the terminal state
            return WriteJsonResponseAsync(httpContext.Response, obj, jsonTypeInfo);
        }
    }

So instead of returning

return response.Negotiate(data);

I have to wrap the response in an IResult wrapper so that it hits the 1st conditional block in ExecuteReturnAsync.

return Results.Extensions.Negotiated(response.Negotiate(data));
public static class NegotiatedResultExtensions
{
    public static IResult Negotiated(this IResultExtensions _, Task obj)
    {
        return new NegotiatedResult(obj);
    }

    private class NegotiatedResult : IResult
    {
        private readonly Task _item;
    
        public NegotiatedResult(Task item)
        {
            _item = item;
        }

        public Task ExecuteAsync(HttpContext httpContext)
        {
            return _item;
        }
    }

toddsmith-adsk avatar Nov 23 '24 19:11 toddsmith-adsk