Home > Software design >  How ApplicationBuilder set 404 status code in a RequestDelegate?
How ApplicationBuilder set 404 status code in a RequestDelegate?

Time:01-09

https://source.dot.net/#Microsoft.AspNetCore.Http/Builder/ApplicationBuilder.cs,132

public class ApplicationBuilder : IApplicationBuilder {

   private readonly List<Func<RequestDelegate, RequestDelegate>> _components = new();
   ...
   public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware) {   
      _components.Add(middleware);
      return this;
   }

   public RequestDelegate Build() {
      RequestDelegate app = context => {  
         ...
         context.Response.StatusCode = StatusCodes.Status404NotFound;
         return Task.CompletedTask;
      }
   }

   for (var c = _components.Count - 1; c >= 0; c--) { 
      app = _components[c](app);
   }
   return app;
}

As you can see, the RequestDelegate app will always be executed, which means the status code will be set to 404, which doesn't make sense at all. For me, the code should be sth like:

public RequestDelegate Build() {
   RequestDelegate app = context => {
      ...
      if (context.Response has not been set) {  // pesudo code
         context.Response.StatusCode = StatusCodes.Status404NotFound;
      }      
      return Task.CompletedTask;
   }
}

CodePudding user response:

This code assumes that you have already added the endpoint middleware: https://github.com/aspnet/Routing/blob/master/src/Microsoft.AspNetCore.Routing/EndpointMiddleware.cs

// If we reach the end of the pipeline, but we have an endpoint, then something unexpected has happened.
// This could happen if user code sets an endpoint, but they forgot to add the UseEndpoint middleware.

In the endpoint middleware:

        public async Task Invoke(HttpContext httpContext)
        {
            var endpoint = httpContext.Features.Get<IEndpointFeature>()?.Endpoint;
            if (endpoint?.RequestDelegate != null)
            {
                Log.ExecutingEndpoint(_logger, endpoint);

               try
                {
                    await endpoint.RequestDelegate(httpContext);
                }
                finally
                {
                    Log.ExecutedEndpoint(_logger, endpoint);
                }
                return;
            }

            await _next(httpContext);
        }

So the code you shared, handled the non existence of an endpoint, thus returning 404.

  •  Tags:  
  • Related