如何将 cookie 值设置为 MapRoute 参数的默认值?

How to set cookie value as default value for MapRoute parameter?

简介:

我开发多语言网络应用程序。管理员可以创建新语言(此信息存储在数据库中)。所以语言没有硬编码在代码中的某个地方。用户的首选语言存储在浏览器 cookie 中。

现在我想配置 url 路由:

www.host.com/home/about

对此:

www.host.com/{lang}/home/about

RouteConfig.cs 看起来像:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.LowercaseUrls = true;

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

        foreach (Route r in routes)
        {
            r.Url = "{lang}/" + r.Url;
            if (r.Defaults == null)
                r.Defaults = new RouteValueDictionary();
            r.Defaults.Add("lang", ServiceLocalization.GetLanguageFromBrowserCookie());
        }
    }
}

每个请求都会添加参数 {lang} url。我需要从 cookie 设置默认值。服务方法 GetLanguageFromBrowserCookie() 使用 HttpContext.Current.Request.Cookies 对象访问客户端发送的 cookie。

但是 HttpContext.Current.Request 对象在请求处理管道的这个阶段不可访问。我得到这个错误:"Request is not available in this context"

有没有办法用 cookie 值获取 MapRoute 参数?

好的。我想出了如何做到这一点。我们需要创建自定义 RouteHandler 来处理具有额外逻辑的请求 url。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.LowercaseUrls = true;

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        ).RouteHandler = new CustomRouteHandler();
    }
}
public class CustomRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var route = (Route)requestContext.RouteData.Route;

        if (!route.Url.Contains("{lang}"))
            route.Url = "{lang}/" + route.Url;
        if (route.Defaults == null)
        {
            route.Defaults = new RouteValueDictionary();
            route.Defaults.Add("lang", ServiceLocalization.GetLanguageFromBrowserCookie().CodeName);
        }
        else
        {
            route.Defaults["lang"] = ServiceLocalization.GetLanguageFromBrowserCookie().CodeName;
        }

        return base.GetHttpHandler(requestContext);
    }
}

我创建 CustomRouteHandler 并将其传递给默认路由。在 GetHttpHandler 方法中,我们可以访问当前的 HttpRequest 并从请求中获取任何数据。