Asp.net mvc 3 带ActionLink的ASP MVC 3交换语言

Asp.net mvc 3 带ActionLink的ASP MVC 3交换语言,asp.net-mvc-3,localization,Asp.net Mvc 3,Localization,在ASP MVC 3项目中,我希望启用语言切换 路由的定义如下: routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "DefaultWithLanguage", // Route name "{language}/{controller}/{id}/{slug}", // URL with parameters new

在ASP MVC 3项目中,我希望启用语言切换

路由的定义如下:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
             "DefaultWithLanguage", // Route name
             "{language}/{controller}/{id}/{slug}", // URL with parameters
             new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = UrlParameter.Optional } // Parameter defaults                 
         );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>    
.../en/ControllerName/Id
.../en/ControllerName/Id/Slug
.../en/ControllerName
尝试切换语言(在_Layout.cshtml中)的工作方式如下:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
             "DefaultWithLanguage", // Route name
             "{language}/{controller}/{id}/{slug}", // URL with parameters
             new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = UrlParameter.Optional } // Parameter defaults                 
         );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>    
.../en/ControllerName/Id
.../en/ControllerName/Id/Slug
.../en/ControllerName
我明白了:

.../ControllerName/ActionName?Length=11
如果我将ActionLink设置为以下值(请注意最后一个null参数):

我错过了什么?
提前谢谢

您的路线注册存在一些问题
DefaultWithLanguage
路线注册。它不允许您指定
{action}
。这意味着此路由将只匹配
详细信息
操作(因为您已在默认值中指定了它)。另一个问题是您将
{id}
参数设置为可选。但那是不可能的。只有路由的last参数是可选的。在您的例子中,它后面跟着一个
{slug}
参数

因此,一种可能性是:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "DefaultWithLanguage",
        "{language}/{controller}/{action}/{id}",
        new 
        { 
            language = "en", 
            controller = "Front", 
            action = "Details", 
            id = UrlParameter.Optional 
        }
    );
}
然后:

@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { language = "es" },
    null
)
@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { 
        language = "es", 
        id = ViewContext.RouteData.GetRequiredString("id") 
    },
    null
)
如果要添加
{slug}
参数,则
{id}
不再是可选的:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "DefaultWithLanguage",
        "{language}/{controller}/{action}/{id}/{slug}",
        new 
        { 
            language = "en", 
            controller = "Front", 
            action = "Details", 
            slug = UrlParameter.Optional 
        }
    );
}
然后:

@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { language = "es" },
    null
)
@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { 
        language = "es", 
        id = ViewContext.RouteData.GetRequiredString("id") 
    },
    null
)

您的路线注册
DefaultWithLanguage
路线注册存在一些问题。它不允许您指定
{action}
。这意味着此路由将只匹配
详细信息
操作(因为您已在默认值中指定了它)。另一个问题是您将
{id}
参数设置为可选。但那是不可能的。只有路由的last参数是可选的。在您的例子中,它后面跟着一个
{slug}
参数

因此,一种可能性是:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "DefaultWithLanguage",
        "{language}/{controller}/{action}/{id}",
        new 
        { 
            language = "en", 
            controller = "Front", 
            action = "Details", 
            id = UrlParameter.Optional 
        }
    );
}
然后:

@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { language = "es" },
    null
)
@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { 
        language = "es", 
        id = ViewContext.RouteData.GetRequiredString("id") 
    },
    null
)
如果要添加
{slug}
参数,则
{id}
不再是可选的:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "DefaultWithLanguage",
        "{language}/{controller}/{action}/{id}/{slug}",
        new 
        { 
            language = "en", 
            controller = "Front", 
            action = "Details", 
            slug = UrlParameter.Optional 
        }
    );
}
然后:

@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { language = "es" },
    null
)
@Html.ActionLink(
    "Spanish", 
    ViewContext.RouteData.GetRequiredString("action"), 
    ViewContext.RouteData.GetRequiredString("controller"),
    new { 
        language = "es", 
        id = ViewContext.RouteData.GetRequiredString("id") 
    },
    null
)

这是达林回答的后续问题

我想要这样的路线:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
             "DefaultWithLanguage", // Route name
             "{language}/{controller}/{id}/{slug}", // URL with parameters
             new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = UrlParameter.Optional } // Parameter defaults                 
         );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>    
.../en/ControllerName/Id
.../en/ControllerName/Id/Slug
.../en/ControllerName
这最后一条路线导致了问题(参见Darin的答案)。继续获取此路由的“黑客”是定义另一个路由(第二个名为DefaultWithLanguageWithoutId):

这导致母版页中的代码调整为以下值

    <li>@Html.ActionLink("Deutsch", ViewContext.RouteData.Values["action"].ToString()
, ViewContext.RouteData.Values["controller"].ToString(), new { language = "de"
, id = ViewContext.RouteData.Values["id"]!=null ? ViewContext.RouteData.Values["id"].ToString():null }, null)</li>
    <li>@Html.ActionLink("English", ViewContext.RouteData.Values["action"].ToString()
, ViewContext.RouteData.Values["controller"].ToString(), new { language = "en"
, id = ViewContext.RouteData.Values["id"] != null ? ViewContext.RouteData.Values["id"].ToString() : null }, null)</li>  
  • @Html.ActionLink(“Deutsch”,ViewContext.RouteData.Values[“action”].ToString() ,ViewContext.RouteData.Values[“controller”].ToString(),新{language=“de” ,id=ViewContext.RouteData.Values[“id”]!=null?ViewContext.RouteData.Values[“id”]。ToString():null},null)
  • @ActionLink(“英语”,ViewContext.RouteData.Values[“action”].ToString() ,ViewContext.RouteData.Values[“controller”].ToString(),新{language=“en” ,id=ViewContext.RouteData.Values[“id”!=null?ViewContext.RouteData.Values[“id”]。ToString():null},null)
  • 工作完美


    唯一的“缺点”是视图中包含一些代码(我希望避免),但我认为这是值得的,因为它非常简单

    这是达林回答的后续问题

    我想要这样的路线:

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
            routes.MapRoute(
                 "DefaultWithLanguage", // Route name
                 "{language}/{controller}/{id}/{slug}", // URL with parameters
                 new { language = "en", controller = "Front", action = "Details", id = UrlParameter.Optional, slug = UrlParameter.Optional } // Parameter defaults                 
             );
    
            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );
    
    <li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>    
    
    .../en/ControllerName/Id
    .../en/ControllerName/Id/Slug
    .../en/ControllerName
    
    这最后一条路线导致了问题(参见Darin的答案)。继续获取此路由的“黑客”是定义另一个路由(第二个名为DefaultWithLanguageWithoutId):

    这导致母版页中的代码调整为以下值

        <li>@Html.ActionLink("Deutsch", ViewContext.RouteData.Values["action"].ToString()
    , ViewContext.RouteData.Values["controller"].ToString(), new { language = "de"
    , id = ViewContext.RouteData.Values["id"]!=null ? ViewContext.RouteData.Values["id"].ToString():null }, null)</li>
        <li>@Html.ActionLink("English", ViewContext.RouteData.Values["action"].ToString()
    , ViewContext.RouteData.Values["controller"].ToString(), new { language = "en"
    , id = ViewContext.RouteData.Values["id"] != null ? ViewContext.RouteData.Values["id"].ToString() : null }, null)</li>  
    
  • @Html.ActionLink(“Deutsch”,ViewContext.RouteData.Values[“action”].ToString() ,ViewContext.RouteData.Values[“controller”].ToString(),新{language=“de” ,id=ViewContext.RouteData.Values[“id”]!=null?ViewContext.RouteData.Values[“id”]。ToString():null},null)
  • @ActionLink(“英语”,ViewContext.RouteData.Values[“action”].ToString() ,ViewContext.RouteData.Values[“controller”].ToString(),新{language=“en” ,id=ViewContext.RouteData.Values[“id”!=null?ViewContext.RouteData.Values[“id”]。ToString():null},null)
  • 工作完美


    唯一的“缺点”是视图中包含一些代码(我希望避免),但我认为这是值得的,因为它非常简单

    您是否也离开了默认路线?请出示您所有的路线登记。@Darin看一下(更改的)公式。我已将所有代码都包含在RegisterRoutes中。您是否也保留了默认路由?请出示您所有的路线登记。@Darin看一下(更改的)公式。我已经在RegisterRoutes中包含了所有代码。现在我明白了!你说得对!非常感谢你的解释!我要试试这个!现在我明白了!你说得对!非常感谢你的解释!我要试试这个!