[SOLVED] How to do a health check on a POST url in ASP.NET/blazor

Issue

I am trying to implement health checks in my blazor application. To do so, I have used the Microsoft.AspNetCore.Diagnostics.HealthChecks package among others. Below you can see sql and url health checks.

startup.cs

//using AjuaBlazorServerApp.Data;
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AjuaBlazorServerApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();
            services.AddHostedService<PeriodicExecutor>();
            services.AddHealthChecks().AddUrlGroup(new Uri("https://api.example.com/post"),
                name: "Example Endpoint",
                failureStatus: HealthStatus.Degraded)
            .AddSqlServer(Configuration["sqlString"],
                healthQuery: "select 1",
                failureStatus: HealthStatus.Degraded,
                name: "SQL Server");
            services.AddHealthChecksUI(opt =>
            {
                opt.SetEvaluationTimeInSeconds(5); //time in seconds between check    
                opt.MaximumHistoryEntriesPerEndpoint(60); //maximum history of checks    
                opt.SetApiMaxActiveRequests(1); //api requests concurrency    
                opt.AddHealthCheckEndpoint("Ajua API", "/api/health"); //map health check api    
            }).AddInMemoryStorage();
        }

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

            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
                endpoints.MapHealthChecks("/api/health", new HealthCheckOptions()
                {
                    Predicate = _ => true,
                    ResponseWriter = UIResponseWriter.
                    WriteHealthCheckUIResponse
                });
                endpoints.MapHealthChecksUI();
            });
        }
    }
}

The sql one works perfectly. However the url health check returns the following error:

Discover endpoint #0 is not responding with code in 200...299 range, the current status is MethodNotAllowed.

What i would like to know is if there is a way to maybe set the method type and if need be send some test details to the endpoint so that we can actually get a valid response.

Solution

AddUrlGroup has an overload that allows you to specify the method through the httpMethod parameter. Try using :

.AddUrlGroup(new Uri("https://api.example.com/post"),
            httpMethod: HttpMethod.Post,
            name: "Example Endpoint",
            failureStatus: HealthStatus.Degraded)

Another overload allows configuring the HttpClient and HttpMessageHandler explicitly, to add specific default headers for example, enable compression or redirection.

.AddUrlGroup(new Uri("https://api.example.com/post"),
            httpMethod: HttpMethod.Post,
            name: "Example Endpoint",
            configureClient: client => {
                client.DefaultRequest.Headers.IfModifiedSince=
                                DateTimeOffset.Now.AddMinutes(-10);
            },
            failureStatus: HealthStatus.Degraded)

Yet another overload allows explicitly configuring the UriHealthCheckOptions class generated by other AddUrlGroup overloads:

.AddUrlGroup(uriOptions=>{
    uriOptions
        .UsePost()
        .AddUri(someUrl,setup=>{
            setup.AddCustomHeader("...","...");
    });
});

There’s no way to specify content headers because the health check code doesn’t send a body.

Answered By – Panagiotis Kanavos

Answer Checked By – Candace Johnson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *