Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正在寻找一个C#URL路由器,但不是HTTP_C#_Url Routing_Mqtt - Fatal编程技术网

正在寻找一个C#URL路由器,但不是HTTP

正在寻找一个C#URL路由器,但不是HTTP,c#,url-routing,mqtt,C#,Url Routing,Mqtt,我正在寻找一个C#URL路由器组件。非常经典的东西,获取输入字符串,如/resources/:id/stuff,并调用适当的方法。类似于默认ASP.net路由或。 但是,我不使用HTTP,也不想要完整的HTTP堆栈/框架。我正在寻找一些轻路由我的MQTT消息。 您知道是否存在这样的组件吗?以下非优化、非真正防御性编码的代码针对路由解析URI: public class UriRouteParser { private readonly string[] _routes; pub

我正在寻找一个C#URL路由器组件。非常经典的东西,获取输入字符串,如
/resources/:id/stuff
,并调用适当的方法。类似于默认ASP.net路由或。 但是,我不使用HTTP,也不想要完整的HTTP堆栈/框架。我正在寻找一些轻路由我的MQTT消息。
您知道是否存在这样的组件吗?

以下非优化、非真正防御性编码的代码针对路由解析URI:

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;
    }
}

这将产生一个
{“id”=“42”}
字典,您可以随意使用它。

我很快改变了@CodeCaster的解决方案,以附加和调用委托

public class UriRouter
{
    // Delegate with a context object and the route parameters as parameters
    public delegate void MethodDelegate(object context, Dictionary<string, string> parameters);

    // Internal class storage for route definitions
    protected class RouteDefinition
    {
        public MethodDelegate Method;
        public string RoutePath;
        public Regex RouteRegEx;

        public RouteDefinition(string route, MethodDelegate method)
        {
            RoutePath = route;
            Method = method;

            // 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]+)");

            // Build the match uri parameter to that regex.
            RouteRegEx = new Regex(routeFormat);
        }
    }

    private readonly List<RouteDefinition> _routes;

    public UriRouter()
    {
        _routes = new List<RouteDefinition>();
    }

    public void DefineRoute(string route, MethodDelegate method)
    {
        _routes.Add(new RouteDefinition(route, method));
    }

    public void Route(string uri, object context)
    {
        foreach (var route in _routes)
        {
            // Execute the regex to check whether the uri correspond to the route
            var match = route.RouteRegEx.Match(uri);

            if (!match.Success)
            {
                continue;
            }

            // Obtain named groups.
            var result = route.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);

            // Invoke the method
            route.Method.Invoke(context, result);

            // Only the first match is executed
            return;
        }

        // No match found
        throw new Exception("No match found");
    }
}

这将在标准输出上打印
42-abcd

对于不熟悉RestfulRouting的人,您能确切解释一下它的功能吗?您能解释一下如何从字符串调用方法吗?您只是希望通过
/
分割并获取相对URI的部分吗?此外,对库的请求与堆栈溢出无关,因此最好只描述如何准确地执行您想要执行的操作。它将根据路由调用一个方法。一个非常简单的路由器可以通过
/
进行拆分,并使用几个
交换机
块。更高级的路由器将提供一个简单的API和一些解析方法。这在HTTP框架(Rails、Express、CakePHP…)中非常常见。您现在如何实现mqtt?是的,我知道web应用程序中的路由是什么,只是不清楚您到底在寻找什么功能。@montewhizdoh:我使用。非常感谢。我为您的解决方案添加了委托,这正是我所需要的:-)可以应用的第一个优化是在构造函数中预构建正则表达式,而不是每个方法调用。您可能还需要添加一些参数检查,例如具有重复变量名或根本没有变量的路由。是的,我只更新了一次代码以构建正则表达式。
public class UriRouter
{
    // Delegate with a context object and the route parameters as parameters
    public delegate void MethodDelegate(object context, Dictionary<string, string> parameters);

    // Internal class storage for route definitions
    protected class RouteDefinition
    {
        public MethodDelegate Method;
        public string RoutePath;
        public Regex RouteRegEx;

        public RouteDefinition(string route, MethodDelegate method)
        {
            RoutePath = route;
            Method = method;

            // 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]+)");

            // Build the match uri parameter to that regex.
            RouteRegEx = new Regex(routeFormat);
        }
    }

    private readonly List<RouteDefinition> _routes;

    public UriRouter()
    {
        _routes = new List<RouteDefinition>();
    }

    public void DefineRoute(string route, MethodDelegate method)
    {
        _routes.Add(new RouteDefinition(route, method));
    }

    public void Route(string uri, object context)
    {
        foreach (var route in _routes)
        {
            // Execute the regex to check whether the uri correspond to the route
            var match = route.RouteRegEx.Match(uri);

            if (!match.Success)
            {
                continue;
            }

            // Obtain named groups.
            var result = route.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);

            // Invoke the method
            route.Method.Invoke(context, result);

            // Only the first match is executed
            return;
        }

        // No match found
        throw new Exception("No match found");
    }
}
var router = new UriRouter();

router.DefineRoute("/resources/:id/stuff",
    (context, parameters) => Console.WriteLine(parameters["id"] + " - " + context)); 

router.Route("/resources/42/stuff", "abcd");