Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.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
Asp.net mvc Asp.Net MVC路由未按5.1中的预期工作_Asp.net Mvc_Asp.net Mvc Routing_Attributerouting - Fatal编程技术网

Asp.net mvc Asp.Net MVC路由未按5.1中的预期工作

Asp.net mvc Asp.Net MVC路由未按5.1中的预期工作,asp.net-mvc,asp.net-mvc-routing,attributerouting,Asp.net Mvc,Asp.net Mvc Routing,Attributerouting,我需要将区域性添加到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中。但是,一旦我将这个测试应用程序升级到MVC5.1,链接中就不再生成区域性,如果您手动将其键入url,就会出现404错误 我压缩了我的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中。但是,一旦我将这个测试应用程序升级到MVC5.1,链接中就不再生成区域性,如果您手动将其键入url,就会出现404错误

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

在这个测试应用程序中,Home/About操作有一个路由属性应用于它
[Route(“About”)]
,当生成该路由的链接时,它应该是
localhost/en/About
,但它只是
localhost/About
。如果在地址栏中键入
localhost/en/about
,MVC5.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");
    }
}

好的,我知道了。MVC5.1引入了突破性的变化。在上面的代码中有一个foreach循环,它动态地更改所有路由URL以附加“{culture}/”占位符。e、 g路由
about
变为
{culture}/about
,依此类推

这在5.0中有效,因为路由的类型为System.Web.Routing.Route。在5.1中,他们引入了一系列附加类。其中之一称为LinkGenerationRoute,用于通过属性路由应用的所有路由。该类保留原始路由的私有只读引用,该引用是在最初调用
routes.mapmvcattributteroutes()时生成的用于注册基于属性的路由。然后,该类通过将其单个属性发送到它从中继承的基类:Route来克隆该路由

在foreach循环中,我有效地修改了基类的Url,但不是LinkGenerationRoute所持有的内部引用的Route对象。其效果是,框架中现在有两个路由实例,我们只能在创建了基础路由后修改它。不幸的是,内部路由(_innerRoute)用于获取虚拟路径,因此导致链接生成错误,因为创建后无法对其进行修改

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

在这一天结束时,我认为在这个类中保留对路线的内部引用没有任何意义。应使用当前实例。e、 g.
this.GetVirtualPath(请求上下文,值)


在for循环的
和方法调用中,您只是将区域性默认为“en”吗?我不知道这是怎么回事。我不确定我是否理解你的解决方案。在我们的例子中,我们没有使用区域性,但RouteConfig在MapMvcAttributeRoutes()调用中失败,出现以下错误::无法调用操作方法“System.Web.Mvc.PartialViewResult ErrorView[T](T,System.String,System.String,System.String),System.String)“”在控制器“name here”上,因为操作方法是通用方法。你知道我们应该做些什么来修复它吗?他们到底为什么要改变这个。使用内部属性和此格式有什么好处?您的第一个解决方案非常优雅,它建立在整个ASP.NET堆栈的可扩展性之上。这个解决方案是朝相反方向迈出的一步
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);
    }
}