Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for a C# URL router, but not for HTTP

I am looking for a C# URL router component. Something very classic, taking inputs string such as /resources/:id/stuff and calling the appropriate methods. Something similar to the default ASP.net routing or RestfullRouting. However, I am not using HTTP and I don't want a full HTTP stack/framework. I am looking for something light to route my MQTT messages. Do you know if such a component exist?

like image 514
e741af0d41bc74bf854041f1fbdbf Avatar asked Dec 05 '25 07:12

e741af0d41bc74bf854041f1fbdbf


1 Answers

The following non-optimized, not really defensively coded code parses URIs against routes:

public class UriRouteParser
{
    private readonly string[] _routes;

    public UriRouteParser(IEnumerable<string> routes)
    {
        _routes = routes.ToArray();
    }

    public Dictionary<string, string> GetRouteValues(string uri)
    {
        foreach (var route in _routes)
        {
            // Build RegEx from route (:foo to named group (?<foo>[a-z0-9]+)).
            var routeFormat = new Regex("(:([a-z]+))\\b").Replace(route, "(?<$2>[a-z0-9]+)");

            // Match uri parameter to that regex.
            var routeRegEx = new Regex(routeFormat);

            var match = routeRegEx.Match(uri);

            if (!match.Success)
            {
                continue;
            }

            // Obtain named groups.
            var result = routeRegEx.GetGroupNames().Skip(1) // Skip the "0" group
                                   .Where(g => match.Groups[g].Success && match.Groups[g].Captures.Count > 0)
                                   .ToDictionary(groupName => groupName, groupName => match.Groups[groupName].Value);
            return result;
        }

        // No match found
        return null;
    }
}

It makes a few assumptions about the input (both routes and URIs), but basically it picks the :foo parameter names from the routes and makes named capture groups from that, which are matched against the input URI.

To be used like this:

var parser = new UriRouteParser(new []{ "/resources/:id/stuff" });
var routeValues = parser.GetRouteValues("/resources/42/stuff");

This will yield a dictionary of { "id" = "42" }, which you can then use as you like.

like image 105
CodeCaster Avatar answered Dec 06 '25 21:12

CodeCaster



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!