Posts Tagged ‘aspnetcore’

Health middleware in AspnetCore, or rather Dotnet6 throws TaskCanceledException

January 21st, 2022

I added some health check to my aspnet site to trigger from Kubernetes startupProbe and sometimes got

{
	"EventId": 1,
	"LogLevel": "Error",
	"Category": "Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware",
	"Message": "An unhandled exception has occurred while executing the request.",
	"Exception": "System.Threading.Tasks.TaskCanceledException: A task was canceled.    
        at Microsoft.Extensions.Diagnostics.HealthChecks.DefaultHealthCheckService.CheckHealthAsync(Func`2 predicate, CancellationToken cancellationToken)    
        at Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckMiddleware.InvokeAsync(HttpContext httpContext)    
        at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)    
        at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)    
        at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)",
	"State": {
		"Message": "An unhandled exception has occurred while executing the request.",
		"{OriginalFormat}": "An unhandled exception has occurred while executing the request."
	}
}

There is nothing in my health checking code that can throw (famous last words…). In the stack above there is none of my code.

There might be a call to cancel that results in a TaskCanceledException or something with authentication/authorisation as can be seen in the stack.

To make a long story short I moved the calls to UseHealthCheck from below UseEndpoints to above UseAuthentication as my endpoints are anonymous (they are very lightweight).

app.UseRouting();

app.UseHealthChecks("/api/article/health/alive", new HealthCheckOptions
{
    Predicate = check => true
});
app.UseHealthChecks("/api/article/health/ready", new HealthCheckOptions
{
    Predicate = check => true
});
app.UseHealthChecks("/api/article/health/startup", new HealthCheckOptions
{
    Predicate = check => true
});

app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

Starting an Aspnet core site on IISExpress

April 16th, 2020

One cannot point at a folder and just start, as we did with the full framework. There seems to be several solutions for Core and the one described here requires a publish. (Visual studio 2017:menu->Build->Publish)

Publishing a dotnet core site copies relevant parts to a folder

"path\iisexpress.exe" /path:"path\site\bin\Debug\netcoreapp2.2\publish" /port:betweenmagicalnumbers

Here is the exact command I recently used.

"C:\Program Files\IIS Express\iisexpress.exe" /path:"C:\DATA\PROJEKT\Lagardsdorren\Lagardsdorren\bin\Debug\netcoreapp2.2\publish" /port:44342

The port number is limited to 44300 to 44399 to avoid having to start Visual studio with elevated privileges. Reference.

Do not walk the path with “..” as you get an “Invalid physical path.” error.

Set an environment variable to give better debug output. Reference.

$Env:ASPNETCORE_ENVIRONMENT = "Development"

Simple connect a mongo client container to a mongodb container

August 14th, 2017

I tried this on OSX. It probably works on Windows too.

In this article we create a container with mongodb and some contents and then connect to it from another container.
Just for personal reasons the client container is really a “aspnet container” and not connected to mongodb to start with.

Even though I liked typing my way around Docker I tried and discovered the free Kitematic by Docker.
It gives me a very simple overview but I hope it to evolve some in the future to include a little more, like the git-githubdesktop-sourcetree journey.


Create a mongo database with contents

Open Kitematic and create a mongodb container.

Select Exec to get a terminal.

Now, inside the container, connect to the built-in mongo:

mongo

Just for fun, see what databases we have:

show dbs

Create two new records.

db.runCommand({insert:"projects", documents:[{_id:1, name:"Alpha"}] })
db.runCommand({insert:"projects", documents:[{_id:2, name:"Beta"}] })

The result should be

{ "n" : 1, "ok" : 1 }

for each call where “n” denotes the number of records inserted and “ok” the success.

See what we have  of databases again, to find the new database “projects”.

show dbs

Step into the database: (Is this really necessary?)

use projects

Query what we have:

db.runCommand({find:"projects"})

Now we have a container running mongodb with data in it.
You can leave mongodb and the container but make sure it is not stopped.

Create another container

Containerising is about selecting an image and then adapting it to you needs.
I use a lot of dotnet and hence choose to select a dotnet core image.

Search in Kitematic for “aspnetcore” and select one. Which to chose can be complex; by the time of writing there are 2 from Microsoft. Which to choose is another subject and also subject to change.

When the container is started update it and then install mongodb.

apt-get update

apt-get install mongodb

Note: Updating the container with apt-get is something one probably don’t do as such tasks should be scripted. But here we are experimenting.

We don’t want the database in this container, only the client, but is easier to find an apt-get for the whole database than for just a client.

We now have 2 running containers and if you didn’t fiddle around too much they are sharing network.
The network can be inspected:

docker network inspect bridge

which results in something like:

        "Containers": {
             "2fae...eb2a": {
                 "Name": "aspnetcore",
                 ...
                 "IPv4Address": "172.17.0.3/16",
                 ...
 },
             "f565...3856": {
                 "Name": "mongo",
                 ...
                 "IPv4Address": "172.17.0.2/16",
                 ...
 }

There we have the IP addresses. Out of the box Docker containers don’t have a name resolution so we’ll use the IP address to connect.

So connect with:

mongo 172.17.0.2

and query as before:

db.runCommand({find:"projects"})

Yay!
Two connected containers, one running a mongo database and one connected to it and prepared for aspnetcore love.