Сделать URL-адрес для конкретного языка (через маршруты)

Трудно найти ответ на этот конкретный вопрос, так что всерьёз его здесь:

Мы хотим, чтобы наши URL были полностью привязаны к языку, что означает

www.mysite.com/EN

www.mysite.com/DE

это выполняется в RouteConfig с

url: "{language}/{controller}/{action}/{id}"

Но тогда сложная часть:

www.mysite.com/EN/Categories

www.mysite.com/DE/Kategorien

т.е. сделать controllername появляться на нескольких языках, но указать на тот же контроллер. Возможно ли это?

Ответ 1

Ну, это частично возможно (только часть языка). Имя контроллера на другом языке - определенно интересный момент, но я думаю, что этого будет трудно. Подумайте, как это будет выглядеть для биди-языков, таких как арабский и иврит. Вероятно, было бы неплохо использовать контроллер на разных языках, но вы бы создали хаос для себя, и я считаю, что вам нужно будет изменить базовую структуру MVC, чтобы это разрешить.

Часть изменения языка легко и может быть выполнена, как показано ниже.

То, что вы, возможно, захотите посмотреть, - это глобализация. В основном языковая часть соответствует текущей культуре пользовательского интерфейса. Вам нужно следующее:

  • Определите маршрут, например:

    var lang = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
    
    routes.MapRoute(
        name: "Default",
        url: "{language}/{controller}/{action}/{id}",
        defaults: new { language = lang, controller = "Home", 
                        action = "Index", id = UrlParameter.Optional }
     );
    
  • Зарегистрируйте Application_AcquireRequestState и определите его примерно так:

    protected void Application_AcquireRequestState()
    {
        var routes = RouteTable.Routes;
    
        var httpContext = Request.RequestContext.HttpContext;
        if (httpContext == null) return;
    
        var routeData = routes.GetRouteData(httpContext);
    
        var language = routeData.Values["language"] as string;
        var cultureInfo = new CultureInfo(language);
    
        System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
        System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
    }
    

    Хотя CurrentUICulture - это то, что вам нужно, чтобы загружать информацию языков языков из файла ресурсов, вы также должны изменить CurrentCulture на тот же CultureInfo;

  • Наконец, убедитесь, что у вас есть соответствующие файлы ресурсов и резервный файл ресурсов.

Я использовал Name свойство CultureInfo, чтобы вы были немецкими де-DE, английскими en-US и т.д. Это должно сделать трюк.

Если вам нужна дополнительная информация, я могу загрузить образец MVC для изучения.

UPDATE: один грубый способ сделать то, что вы хотите, - инвертировать порядок сегментов маршрута примерно так:

routes.MapRoute(
    name: "NewDefault",
    url: "{language}/{id}/{action}/{controller}",
    defaults: new { language = lang, controller = "Home", action = "Index", id = "Category"}
);

Таким образом, вы можете сделать следующий запрос http://www.your_url.com/de/Kategorien. В этом случае Kategorien сопоставляется с id, а не с контроллером. Контроллер остается на английском или немецком языке (в зависимости от того, как вы его назвали), но пользователь видит другой язык. В фоновом режиме ваше представление может выглядеть примерно так:

public ActionResult Index(string id, string categoryName)
{
    // Fetch data based on category name (categoryName)
    return View();
}

Вы можете передать дополнительную информацию в качестве параметров, но вам нужно будет настроить маршрут следующим образом: {language}/{category}/{subcategory}/{action}/{controller}

Просто знайте, что это может стать болью в области шеи в долгосрочной перспективе, и если вы попробуете это, тогда убедитесь, что вы хорошо документировали его.