Search code examples
routes.net-coremiddleware

.net core 2.0 API ignore middleware for invalid routing


I have some validation middleware that returns a specific response if some data is missing.

When I make a call with an invalid URL, the middleware is being executed, and the error is sent in the response, but the error states the validation issue, not that the URL is invalid.

So my question is, how do I setup the configure method so that any invalid URL should not execute the middleware and plainly return a 404 error.

Here is my configure method:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)//, ITimingLogger timingLogger
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        //app.Use(async (HttpContext context, Func<Task> next) =>
        //{
        //    var timer = new Stopwatch();
        //    timer.Start();
        //    await next();
        //    timer.Stop();
        //    timingLogger.LogElapsedTime(context.Request.Method, context.Request.Path, timer.ElapsedMilliseconds);
        //});

        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseMiddleware<RequestResponseLoggingMiddleware>();
        app.UseMiddleware<UnhandledExceptionHandlerMiddleware>();
        app.UseMiddleware<SubscriptionIdValidatorMiddleware>();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

Thanks


Solution

  • Simple Request Pipeline Logger

    Try this instead...

    app.Use(async (HttpContext context, Func<Task> next) =>
    {
        if (context== null) throw new ArgumentNullException(nameof(context));
    
        var sw = Stopwatch.StartNew();
        try
        {
            await next(context);
            sw.Stop();
    
            // do your logging work here
    
            // for example
            if (httpContext.Response?.StatusCode > 499)
            {
                // 500+ error code is a server error
                // log the error
            }
    
        }
        catch (Exception ex) when (LogException(context, sw, ex))
        {
            // never caught, because `LogException()` returns false.         
        }
    }
    

    and then add this static method

    static bool LogException(HttpContext context, Stopwatch sw, Exception ex)
    {
        sw.Stop();
    
        // log the exception
    
        return false;
    }
    

    The Request Pipeline

    To answer your question more directly instead of just giving you a block of code. I believe that you are misunderstanding how the request pipeline behaves. I will try to explain it with your code.

    app.Use(async (HttpContext context, Func<Task> next) =>
    {
        // every single request is currently hitting this middleware
        // even regardless if the URI "exists" or not.
        // to solve this you need to define what is a valid URI
    
        // for example, validate the path
        if (context.Request.Path != "foo")
        {
            return next();  // break out
        }
    
        // if we got this far, that means it was a valid URI
        var timer = new Stopwatch();
        timer.Start();
    
        await next();
    
        timer.Stop();
        // do work
    });
    

    I hope this illustrates how the pipeline works.

    The request pipeline is executed in the order you list. At the moment, there is nothing in your current code that defines what is a "valid" URI.