Error UseHealthChecksUI Unexpected character encountered

Viewed 2001

I'm trying to implement the ASP.NET Core 2.2 health check feature. Setting up the health check itself isn't the problem, but I also want to be able to use the UI feature in other project to monitoring all my apis. Right now I get the exception message

Unexpected character encountered while parsing value: <.

What I'm doing bad?

API Project:

var healthCheckOptions = new HealthCheckOptions
{
Predicate = _ => true,
ResponseWriter = async (c, r) =>
{
    c.Response.ContentType = MediaTypeNames.Application.Json;
    var result = JsonConvert.SerializeObject(
        new
        {
            Checks = r.Entries.Select(e =>
                new
                {
                    Description = e.Key,
                    Status = e.Value.Status.ToString(),
                    ResponseTime = e.Value.Duration.TotalMilliseconds
                }),
            TotalResponseTime = r.TotalDuration.TotalMilliseconds
        });
    await c.Response.WriteAsync(result);
 }
};

app.UseHealthChecks("/live", new HealthCheckOptions
{
  Predicate = _ => true
});
app.UseHealthChecks("/hc", healthCheckOptions);
app.UseHealthChecksUI(options => options.UIPath = "/healtcheck");

// Registers required services for health checks
services
   .AddHealthChecks()
   .AddCheck("self", () => HealthCheckResult.Healthy())
   .AddCheck("ComunContext Database", new   SqlServerHealthCheck(configuration["ConnectionStrings:ComunContext"]));

Web project:

services.AddHealthChecksUI();

app.UseHealthChecksUI(config =>
{
    config.UIPath = "/healthcheck";
});

appsettings.json
{
  "HealthChecks-UI": {
  "HealthChecks": [
  {
    "Name": "Local",
    "Uri": "http://localhost:27365/hc"
  }
],
"EvaluationTimeOnSeconds": 10,
"MinimumSecondsBetweenFailureNotifications": 60
 }
}
2 Answers

Try adding a ResponseWriter:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{      
    app.UseHealthChecks("/healthchecks", new HealthCheckOptions
    {
        ResponseWriter = async (context, report) =>
        {
            context.Response.ContentType = "application/json; charset=utf-8";
            var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(report));
            await context.Response.Body.WriteAsync(bytes);
        }
    });
    app.UseHealthChecksUI();
}

After a few days struggling with this parser error, I've figured out that there are 2 problems: 1 - If you have an Exception, Health UI tries to convert Exception object field, resulting on error; 2 - If you try to pass your own anonymous object, Health UI fails to convert Entries collection, because it need to be an specific anonymous Dictionary.

Try this:

    var healthCheckOptions = new HealthCheckOptions
    {
        Predicate = _ => true,
        ResponseWriter = async (c, r) =>
        {
        c.Response.ContentType = MediaTypeNames.Application.Json;
        var result = JsonConvert.SerializeObject(
            new
            {
                Checks = r.Entries.ToDictionary(
                    e => e.Key,
                    e =>
                    new
                    {
                        Description = e.Key,
                        Status = e.Value.Status.ToString(),
                        ResponseTime = e.Value.Duration.TotalMilliseconds
                    }),
                TotalResponseTime = r.TotalDuration.TotalMilliseconds
            });
        await c.Response.WriteAsync(result);
        }
    };
Related