Asp.Net Core中的自定义IRouter没有任何反应 [英] Nothing happened with custom IRouter in Asp.Net Core

查看:205
本文介绍了Asp.Net Core中的自定义IRouter没有任何反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的路由器实现如下:

public class TenantUrlResolverRouter : IRouter
{
    private readonly IRouter _defaultRouter;

    public TenantUrlResolverRouter(IRouter defaultRouter)
    {
        _defaultRouter = defaultRouter;
    }

    public VirtualPathData GetVirtualPath(VirtualPathContext context)
    {
        return _defaultRouter.GetVirtualPath(context);
    }

    public async Task RouteAsync(RouteContext context)
    {
        var oldRouteData = context.RouteData;
        var newRouteData = new RouteData(oldRouteData);
        newRouteData.Values["library"] = "Default";
        try
        {
            context.RouteData = newRouteData;
            await _defaultRouter.RouteAsync(context);
        }
        finally
        {
            if (!context.IsHandled)
            {
                context.RouteData = oldRouteData;
            }
        }
    }
}

然后我在 Startup.cs 中定义它:

app.UseMvc(routes =>
        {
            routes.Routes.Add(
                new TenantUrlResolverRouter(routes.DefaultHandler));
            routes.MapRoute(
                name: "default",
                template: "{library=Unknown}/{controller=Home}/{action=Index}/{id?}");
        });

但是什么也没发生, RouteData.Values RouteContext 始终为空,我始终为未知,而它需要为 Default 。这不是预定义模板的问题,因为即使没有 {library = Unknown} 和这个 {library} / {controller = Home} / {action = Index} / {id?} 也不起作用。

But nothing happens, RouteData.Values in RouteContext always empty, I always have Unknown, while it's need to be Default. That's not the problem of the predefined template, because it even worked without the {library=Unknown} and this {library}/{controller=Home}/{action=Index}/{id?} doesn't work too.

此自定义IRouter有什么问题?

What's the problem with this custom IRouter?

推荐答案

您没有提供完整的路由值集。为了路由到某个动作,您需要同时提供 controller action

You are not providing a complete set of route values. In order to route to an action, you need to provide both controller and action.

此外,您的路线中没有匹配条件。匹配条件将确定传入的请求是否与当前路由匹配。在内置路由中, url 约束是匹配条件。但是,在自定义路由中,您需要放置 if 块,以确保任何不匹配的请求都将传递到下一条已注册的路由。

Also, you don't have a match condition in the route. A match condition will determine whether the incoming request matches the current route. In the built-in routing, the url and constraints are match conditions. However, in a custom route, you need to put an if block to ensure that any request that doesn't match will pass through to the next registered route.


注意::这是自定义路由功能中最强大的部分。内置路由只能与URL匹配。但是使用自定义路由,您可以匹配请求中的任何内容。例如,您可以使路由仅对某个域或某个子域匹配。您甚至可以使其匹配发布的表单值或会话状态之类的东西。

NOTE: This is the most powerful part of custom routing. The built-in routing can only match against URLs. But with custom routing, you can match anything in the request. For example, you could make the route match only for a certain domain or a certain subdomain. You could even make it match things like posted form values or session state.



public async Task RouteAsync(RouteContext context)
{
    var requestPath = context.HttpContext.Request.Path.Value;

    if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/')
    {
        // Trim the leading slash
        requestPath = requestPath.Substring(1);
    }

    var segments = requestPath.Split('/');

    // Required: Match condition to determine if the incoming request
    // matches this route. If not, you should allow the framework to
    // match another route by doing nothing here.
    if (segments.Length > 0 && segments[0].Equals("libraryname", StringComparison.OrdinalIgnoreCase))
    {
        var oldRouteData = context.RouteData;
        var newRouteData = new RouteData(oldRouteData);
        newRouteData.Values["library"] = segments[0];
        newRouteData.Values["controller"] = segments[1];
        newRouteData.Values["action"] = segments[2];
        try
        {
            context.RouteData = newRouteData;
            await _defaultRouter.RouteAsync(context);
        }
        finally
        {
            if (!context.IsHandled)
            {
                context.RouteData = oldRouteData;
            }
        }
    }
}

查看此问题以获取有关以下信息的更多信息实施 IRouter

See this question for more info about implementing IRouter.

这篇关于Asp.Net Core中的自定义IRouter没有任何反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆