Click here to Skip to main content
15,886,519 members
Articles / Web Development / ASP.NET / ASP.NET Core
Tip/Trick

SignalR Metadata for ASP.NET Core 2.1

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
13 Nov 2018CPOL2 min read 3.8K   2  
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:

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:

JavaScript
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:

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Romania Romania
When asked, I always see myself as a .Net Developer because of my affinity for the Microsoft platform, though I do pride myself by constantly learning new languages, paradigms, methodologies, and topics. I try to learn as much as I can from a wide breadth of topics from automation to mobile platforms, from gaming technologies to application security.

If there is one thing I wish to impart, that that is this "Always respect your craft, your tests and your QA"

Comments and Discussions

 
-- There are no messages in this forum --