W projekcie ASP MVC 3 chcę włączyć przełączanie języków.
Trasowanie definiuje się w następujący sposób:
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
);
Próba przełączenia języków (w _Layout.cshtml) działa tak:
<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" })</li>
Zamiast uzyskiwać adres URL podobny do poniższego (po wybraniu języka hiszpańskiego)
.../es/ControllerName/ActionName
Dostaję to:
.../ControllerName/ActionName?Length=11
Jeśli ustawię ActionLink na następujący (zwróć uwagę na ostatni parametr zerowy):
<li>@Html.ActionLink("Spanish", ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), new { language = "es" }, null)</li>
Rozumiem:
.../ControllerName/ActionName?language=es
Czego mi brakuje? Z góry dziękuję!
2 odpowiedzi
Wystąpiły pewne problemy z rejestracją Twoich tras DefaultWithLanguage
rejestracją tras. Nie pozwala na określenie {action}
. Oznacza to, że ta trasa będzie pasować tylko do akcji Details
(ponieważ określiłeś ją w wartościach domyślnych). Innym problemem jest to, że ustawiłeś parametr {id}
jako opcjonalny. Ale to niemożliwe. Tylko ostatni parametr trasy może być opcjonalny. W Twoim przypadku następuje po nim parametr {slug}
.
Tak więc jedna możliwość jest następująca:
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
}
);
}
I wtedy:
@Html.ActionLink(
"Spanish",
ViewContext.RouteData.GetRequiredString("action"),
ViewContext.RouteData.GetRequiredString("controller"),
new { language = "es" },
null
)
Jeśli chcesz dodać parametr {slug}
, Twój {id}
nie może być już opcjonalny:
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
}
);
}
I wtedy:
@Html.ActionLink(
"Spanish",
ViewContext.RouteData.GetRequiredString("action"),
ViewContext.RouteData.GetRequiredString("controller"),
new {
language = "es",
id = ViewContext.RouteData.GetRequiredString("id")
},
null
)
To jest kontynuacja odpowiedzi Darina.
Chcę mieć takie trasy:
.../en/ControllerName/Id
.../en/ControllerName/Id/Slug
.../en/ControllerName
Ta ostatnia trasa powoduje problem (patrz odpowiedź Darina). „Hakowanie”, aby nadal uzyskiwać te trasy, polega na zdefiniowaniu również innej trasy (druga nazwana DefaultWithLanguageWithoutId) :
public static void RegisterRoutes(RouteCollection routes)
{
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(
"DefaultWithLanguageWithoutId", // Route name
"{language}/{controller}", // URL with parameters
new { language = "en", controller = "Front", action = "Details"} // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Powoduje to dostosowanie kodu na stronie wzorcowej do następującego
<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>
Działa idealnie!
Jedyną „wadą” jest to, że w widoku jest zaangażowany jakiś kod (chciałbym tego uniknąć), ale myślę, że warto, ponieważ jest to bardzo proste!
Podobne pytania
Nowe pytania
asp.net-mvc-3
ASP.NET MVC 3 to trzecia główna wersja rozszerzenia Model-View-Controller do tworzenia aplikacji internetowych w środowisku .NET.