Подтвердить что ты не робот

Как перенаправлять 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.

Возможно ли это?

4b9b3361

Ответ 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-адреса веб-сайтов содержат английский.:)

Ответ 4

Я настоятельно рекомендую следующий подход для реализации многоязычия в веб-приложении MVC 5 (и <), потому что я считаю его наиболее универсальным среди тех, кого я пробовал в последние годы.

Вам в основном нужно реализовать три вещи:

  • Маршрут с поддержкой нескольких языков для обработки входящих URL-адресов (если вы используете MVC5 или выше, вы также можете использовать маршрутизацию на основе атрибутов, но я по-прежнему предпочитаю использовать глобальное правило для отредактируйте это).
  • ЛокализацияAttribute для обработки этих типов запросов на нескольких языках.
  • Вспомогательный метод для создания этих URL внутри вашего приложения (Html.ActionLink и/или Url.Action методы расширения).

См. этот ответ для получения дополнительной информации и образцов кода.

За дополнительной информацией и дополнительными примерами по этой теме вы также можете прочитать этот пост.