加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – Asp.Net MVC路由在5.1中没有按预期工作

发布时间:2020-12-16 09:40:21 所属栏目:asp.Net 来源:网络整理
导读:我需要将文化添加到url以支持我的asp.net mvc应用程序中的本地化,其中url如下:sample.com/en/about sample.com/en/product/2342 我最近将我的应用程序从MVC 5.0升级到5.1但是路由没有按预期工作,因此我创建了一个新的asp.net mvc 5.0测试应用程序,并在几分
我需要将文化添加到url以支持我的asp.net mvc应用程序中的本地化,其中url如下:sample.com/en/about
sample.com/en/product/2342

我最近将我的应用程序从MVC 5.0升级到5.1但是路由没有按预期工作,因此我创建了一个新的asp.net mvc 5.0测试应用程序,并在几分钟内将文化显示在URL中.但是,只要我将此测试应用程序升级到MVC 5.1,就不再在链接中生成文化,如果您手动将其键入URL,则会出现404错误.

我压缩了我的5.0和5.1测试应用程序here.我需要帮助理解为什么这在MVC 5.1中不起作用以及如何纠正它.也许我对路由的理解是有缺陷的,或者这是5.1的合法错误?

在这个测试应用程序中,Home / About操作应用了一个路由属性[Route(“about”)],并且预计当生成该路由的链接时,它应该是localhost / en / about,而是它只是localhost /关于.如果在地址栏中输入localhost / en / about,您将在Mvc 5.1测试应用程序中收到404错误.

以下是在MVC 5.0中有效的相关代码:

public class RouteConfig
{
    private const string STR_Culture = "culture";
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.LowercaseUrls = true;
        routes.MapMvcAttributeRoutes();
        routes.MapRoute(
            name: "Default",url: "{culture}/{controller}/{action}/{id}",defaults: new { culture = "en",controller = "Home",action = "Index",id = UrlParameter.Optional }
        );

        foreach (var item in routes)
        {
            // this works in MVC 5.0
            if (item is Route)
            {
                var route = item as Route;
                if (route.Url.IndexOf("{" + STR_Culture + "}") == -1)
                    route.Url = String.Format("{{{0}}}/{1}",STR_Culture,route.Url);

                //AddCulture(route.Defaults);
            }
        }
    }
    private static void AddCulture(RouteValueDictionary dictionary)
    {
        if (dictionary == null)
            dictionary = new RouteValueDictionary();

        if (dictionary.ContainsKey(STR_Culture) == false)
            dictionary.Add(STR_Culture,"en");
    }
}

解决方法

好吧,想通了. MVC 5.1引入了重大变革.在上面的代码中有一个foreach循环,它动态地更改所有路由URL以附加“{culture} /”占位符.例如,路线约成为{culture} / about等等.

这适用于5.0,因为路由的类型为System.Web.Routing.Route.在5.1中,他们引入了一堆额外的类.其中一个叫做LinkGenerationRoute,用于通过属性路由应用的所有路由.此类保留在初始调用routes期间创建的原始Route的私有只读引用.MapMvcAttributeRoutes();注册基于属性的路线.然后,这个类通过将其各自的属性发送到它继承自的基类来克隆Route:Route.

在foreach循环中,我正在有效地修改base classe的Url,但不是LinkGenerationRoute所持有的内部引用的Route对象.结果是框架内部现在有两个Route实例,我们只能在创建后修改基本实例.不幸的是,内部Route(_innerRoute)用于获取虚拟路径,从而导致链接生成错误,因为它在创建后无法修改.

看起来唯一的方法是在每个路径定义中手动添加此占位符.例如
?[路线(“{culture} / about”)],[路线(“{culture} / contact”)],[路线(“{culture} / product / {productId:int}”)]等.

在一天结束时,我认为没有必要在本课程中持有对路线的内部参考.应该使用当前实例.例如this.GetVirtualPath(requestContext,values);

internal class LinkGenerationRoute : Route
{
    private readonly Route _innerRoute; // original route cannot be modified

    public LinkGenerationRoute(Route innerRoute)
        : base(innerRoute.Url,innerRoute.Defaults,innerRoute.Constraints,innerRoute.DataTokens,innerRoute.RouteHandler) // original route is effectively cloned by sending individual properties to base class
    {
        if (innerRoute == null)
        {
            throw Error.ArgumentNull("innerRoute");
        }

        _innerRoute = innerRoute;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        // Claims no routes
        return null;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext,RouteValueDictionary values)
    {
        // internal route is used for getting the virtual path. fail..
        return _innerRoute.GetVirtualPath(requestContext,values);
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读