Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

SignalR Metadata for ASP.NET Core 2.1

0.00/5 (No votes)
13 Nov 2018 1  
Short post which will tie in with the next post about branching authentication in ASP.NET Core using middleware.

Introduction

This will be a short post which will tie in with the next post about branching authentication in ASP.NET Core using middleware.

The Problem

Recently I encountered a situation in which I needed to pass to a SignalR hub additional data with every request, kinda like environment metadata from external systems. In my case, it was the username from an external system to correlate it.

Of course, the obvious answer would have been that every time I invoked a method on the hub, to also pass along the metadata as a parameter, but that would become cumbersome since this was related to users, so it needed to be in each and every request, cookies were off the table since the requests would be coming from a different domain, and with web sockets involved, it’s not like we can build the request each time like for Ajax calls.

I started looking into additional ways to send information to the hub in such a way that it would always be present from that caller, and also not mess up my method calls.

Some of you might know that the current approach to connect to a SignalR hub now is by using the following snippet of code in JavaScript:

const connection = new signalR.HubConnectionBuilder().withUrl("/hub").build(); // this builds 
                                                                     // the connection for the hub

connection.on("hubMethod", (messages) => { // this is a handler for when the hub reaches 
                                           // the client on the "hubMethod" client endpoint.
alert(messages);
});

connection.start().catch(err => console.error(err.toString())); // here we just start the connection 
                                                            // and log out any errors that might occur.

The Solution

In my case, I wanted to add a username associated with each call so that I can handle it in some custom middleware (which has access to the HttpContext which holds information about the current request). The change for that was actually so minor that it could be easily overlooked, so what I changed to that snippet of code was the following:

const username = "Vlad";
const connection = new signalR.HubConnectionBuilder().withUrl
          (`/hub?UserName=${username}`).build(); // this builds the connection for the hub

connection.on("hubMethod", (messages) => { // this is a handler for when the hub 
                                           // reaches the client on the "hubMethod" client endpoint.
alert(messages);
});

connection.start().catch(err => console.error(err.toString())); // here we just start 
                                 // the connection and log out any errors that might occur.

With this change, if you were to have a look at the request coming in, it will always have that query string attached, and that will be present for all and any future calls from that particular client to the hub.

But How Can I Use That in the Hub?

In this particular case, there was no need to access the HttpContext from the hub since it was going to get used in the middleware before it reaches the hub, but if you have a look at the Context property of a SignalR Hub, you will notice that context isn’t an HttpContext so we will need an extra step to enable us to access the metadata in our hub methods as well.

To get the HttpContext inside of a Hub method, all we need to do is add the following line to the method:

HttpContext httpContext = Context.Features.Get().HttpContext;

Pro Tip

If your metadata is getting too big (which it really shouldn’t), please keep in mind that query strings have a limit on the number of characters that can be sent, so in those cases, it might be worthwhile looking into compressing that string parameter client side and decompressing it server side (maybe we will cover that in a future post 😉 ).

Cheers and happy coding.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here