Как перенаправлять URL-адрес нескольких языков с помощью MVC
Мне нужен многоязычный URL-адрес существующего контроллера. Позвольте мне объяснить подробнее:
У меня есть контроллер с именем "Продукт" и "Просмотр" с именем "Программное обеспечение"; поэтому по умолчанию, если пользователь вводит " http://example.com/en/Product/Software", получите правильный контент (который действительно существует в http://example.com/Product/Software),
Однако, если другой пользователь - французский пользователь - типа http://example.com/fr/Produits/logiciels", должен получить над контроллером и показать с правом content (тот же http://example.com/Product/Software, но с французским текстом).
Примечание. Я установил таблицу маршрутов с помощью "{language}/{controller}/{action}/{id}"
Любой другой недопустимый URL должен показывать страницу 404.
Возможно ли это?
Ответы
Ответ 1
Основываясь на записи Dan, я использую ниже для перевода моего контроллера и имен действий.
Я создал таблицу для хранения значений, это возможно и, вероятно, должно храниться в файлах ресурсов, чтобы сохранить все вместе; однако я использовал таблицу базы данных, поскольку она работает лучше с процессами моих компаний.
CREATE TABLE [dbo].[RoutingTranslations](
[RouteId] [int] IDENTITY(1,1) NOT NULL,
[ControllerName] [nvarchar](50) NOT NULL,
[ActionName] [nvarchar](50) NOT NULL,
[ControllerDisplayName] [nvarchar](50) NOT NULL,
[ActionDisplayName] [nvarchar](50) NOT NULL,
[LanguageCode] [varchar](10) NOT NULL)
Затем файл RouteConfig.cs был изменен на:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//Build up routing table based from the database.
//This will stop us from having to create shedloads of these statements each time a new language, controller or action is added
using (GeneralEntities db = new GeneralEntities())
{
List<RoutingTranslation> rt = db.RoutingTranslations.ToList();
foreach (var r in rt)
{
routes.MapRoute(
name: r.LanguageCode + r.ControllerDisplayName + r.ActionDisplayName,
url: r.LanguageCode + "/" + r.ControllerDisplayName + "/" + r.ActionDisplayName + "/{id}",
defaults: new { culture = r.LanguageCode, controller = r.ControllerName, action = r.ActionName, id = UrlParameter.Optional },
constraints: new { culture = r.LanguageCode }
);
}
}
//Global catchall
routes.MapRoute(
name: "Default",
url: "{culture}/{controller}/{action}/{id}",
defaults: new {culture = CultureHelper.GetDefaultCulture(), controller = "Default", action = "Index", id = UrlParameter.Optional }
//defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
По умолчанию это всегда будет использовать английский контроллер и имена действий, но позволяет вам переопределить, введя значения в таблицу.
(Мой код интернационализации в значительной степени основан на этом замечательном сообщении в блоге.
http://afana.me/post/aspnet-mvc-internationalization-part-2.aspx)
Ответ 2
Как было предложено ранее, это отходит от конвенции, где URL-адреса веб-сайта (и маршруты) используют английский.
Тем не менее, это возможно, но для этого вам, вероятно, придется искать создание одного маршрута для каждого иностранного языка. Таким образом, для сайта с 20 действиями и тремя языками (английский, французский и немецкий) вам понадобятся 41 маршрут (20 французских, 20 немецких и 1 английский). Я признаю, что не самая эффективная система, но она работает так, как вы этого хотите.
//You'll only need one of these, which is the default.
routes.MapRoute(
"English route",
"en/{controller}/{action}/{id}"
new { controller = "Home", action = "Index", language = "en" },
);
routes.MapRoute(
"FrenchHome",
"fr/Demarrer/Index/{id}",
new { controller = "Home", action = "Index", language = "fr" }
);
routes.MapRoute(
"GermanHome",
"de/Heim/Index/{id}", //'Heim' is, I believe the correct usage of Home in German.
new { controller = "Home", action = "Index", language = "de" }
);
//Some more routes...
routes.MapRoute(
"FrenchSoftware",
"fr/Produit/Logiciels/{id}",
new { controller = "Product", action = "Software", language = "fr" }
);
routes.MapRoute(
"GermanSoftware",
"de/Produkt/Software/{id}", //In this instance, Software should be the same in German and English.
new { controller = "Product", action = "Software", language = "de" }
);
//And finally, the 404 action.
routes.MapRoute(
"Catchall",
"{language}/{*catchall}",
new { controller = "Home", action = "PageNotFound", language = "en" },
new { language = "^(en|fr|de)$" }
);
//This is for the folks who didn't put a language in their url.
routes.MapRoute(
"Catchall",
"{*catchall}",
new { controller = "Home", action = "PageNotFound", language = "en" }
);
В ваших действиях, например Product/Software...
public ActionResult Software(string language, int id)
{
//This would go off to the DAL and get the content in whatever language you want.
ProductModel model = ProductService.GetSoftware(language, id);
return View(model);
}
Я бы ЛЮБОВЬ, если бы кто-нибудь пришел и сказал, что есть лучший способ сделать это, потому что я согласен с тем, что наличие URL-адреса на иностранном языке не очень хорошо, и учитывая, что Интернет сама движется к тому, чтобы нелиматические символы в URL-адресах, чем раньше мы рассмотрим решения этого вопроса, тем лучше.
Не только это, но я знаю, что гордые французские люди не любят видеть, что их URL-адреса веб-сайтов содержат английский.:)
Ответ 3
У вас должен быть URL-адрес " http://mysite.com/en/Product/Software" для английского и http://mysite.com/fr/Product/Software" для французского, что имеет смысл.
Используйте тот же вид для обоих.
Счастливое кодирование.
Ответ 4
Я настоятельно рекомендую следующий подход для реализации многоязычия в веб-приложении MVC 5 (и <), потому что я считаю его наиболее универсальным среди тех, кого я пробовал в последние годы.
Вам в основном нужно реализовать три вещи:
- Маршрут с поддержкой нескольких языков для обработки входящих URL-адресов (если вы используете MVC5 или выше, вы также можете использовать маршрутизацию на основе атрибутов, но я по-прежнему предпочитаю использовать глобальное правило для отредактируйте это).
- ЛокализацияAttribute для обработки этих типов запросов на нескольких языках.
- Вспомогательный метод для создания этих URL внутри вашего приложения (
Html.ActionLink
и/или Url.Action
методы расширения).
См. этот ответ для получения дополнительной информации и образцов кода.
За дополнительной информацией и дополнительными примерами по этой теме вы также можете прочитать этот пост.