Локализация / перевод маршрутов в ASP.NET MVC - PullRequest
17 голосов
/ 03 июня 2011

Кто-нибудь знает хорошее решение для локализации маршрутов в ASP.NET MVC?Я хотел бы добиться, чтобы эти два URL указывали на одно и то же действие / ресурс:

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

Я попробовал очень хороший подход Маартена Баллиау , но его решение, к сожалению, не работает с Html.RenderAction(...).

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

routes.MapRoute(
    "Products_Categories",
    "Produkte/Kategorien",
    new { controller = "Products", action = "Categories" }
);

, но это бы привело к огромному количествумаршрутов, и это было бы очень негибко.Любое лучшее решение будет приветствоваться :-) Чем гибче, тем лучше.

Ответы [ 6 ]

2 голосов
/ 12 марта 2012

Вы можете попробовать удивительный проект AttributeRouting , который я только что нашел!Вы можете получить его через NuGet .

2 голосов
/ 01 июля 2011

Это может быть жизнеспособным способом управления всеми вашими маршрутами - или некоторым его вариантом, например определением маршрутов в файле XML

http://www.iansuttle.com/blog/post/ASPNET-MVC-Store-Routes-in-the-Database.aspx

у вас все равно останется большое количество маршрутов, но управлять ими будет намного проще

1 голос
/ 16 июля 2018

Простое решение для как атрибутной, так и обычной маршрутизации можно найти по адресу https://github.com/boudinov/mvc-5-routing-localization

. Вы можете получить их, работая с префиксом / de, так какпредпочтительная схема.Вам необходимо перевести «Продукты» и «Категории» на немецкий язык в файле ресурсов:

Или рабочий ответ на оригинальный вопрос, без языкового префикса, вы можете получить вот так:

0 голосов
/ 17 декабря 2012

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.Web;
using System.Web.Mvc;

public class ProductRoute : RouteBase
{

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;

        string virutalPath = httpContext.Request.Url.AbsolutePath.Substring(1).ToLowerInvariant();

        // Call the database here to retrieve the productId based off of the virtualPath
        var productId = Product.GetProductIdFromVirtualPath(virutalPath);
        if (productId != Guid.Empty)
        {
            result = new RouteData(this, new MvcRouteHandler());
            result.Values["controller"] = "Product";
            result.Values["action"] = "Details";
            result.Values["id"] = productId;
        }

        return result;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        VirtualPathData result = null;
        string controller = Convert.ToString(values["controller"]);
        string action = Convert.ToString(values["action"]);

        if (controller == "Product")
        {
            string path = string.Empty;
            if (action == "Details")
            {
                Guid productId = (Guid)values["id"];

                // Call the database here to get the Virtual Path
                var virtualPath = Product.GetVirtualPathFromProductId(productId);
            }

            if (!String.IsNullOrEmpty(virtualPath))
            {
                result = new VirtualPathData(this, virtualPath);
            }
        }


        return result;
    }

}

Вы можете использовать маршрут, добавив его непосредственно в таблицу маршрутов в Global.asax, например:

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

        routes.MapRoute(
            "home", // Route name
            "", // URL with parameters
            new { controller = "Home", action = "Index" } // Parameter defaults
        );


        // Add your custom route like so
        routes.Add(new ProductRoute());


        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

Затем в вашей локализованной таблице продуктов просто укажите полекоторый содержит путь к поиску (без косой черты).Конечно, вы не упомянули, как храните свои данные, поэтому вам придется придумать это самостоятельно.

Кроме того, вам нужно будет обрабатывать свою локализацию, анализируя ее из virtualPath,Это должно быть там в соответствии с Google.Вы должны обработать исходную культуру на основе переданных заголовков и перенаправить (302) на URL выбранной культуры.Тогда пользователь должен иметь возможность переключать язык, и в этом случае вы можете поместить его в файл cookie, чтобы его предпочтения запомнились.Однако поисковые системы должны быть в состоянии отличить культуру от URL-адреса, не передавая никаких заголовков.

Это будет обрабатывать случай для @ Html.RenderAction () с помощью метода GetVirtualPath (), и вы можете изменить логикуесли нужно.Я рекомендую вам добавить кеширование, потому что при этом каждый запрос попадет в базу данных как есть.Таблица маршрутов заполняется при запуске приложения, но каждый маршрут выполняется при каждом запросе.

Еще одна вещь - для обработки сценария «маршрут не соответствует», просто верните ноль, и маршрутизатор перейдет кследующий настроенный маршрут.Это позволяет настроить столько пользовательских маршрутов, сколько необходимо, без смешивания логики.

0 голосов
/ 13 апреля 2012

MvcCodeRouting имеет возможность форматировать или переводить маршруты, см. эту страницу .

0 голосов
/ 01 июля 2011

Я не уверен, что это правильный подход, по крайней мере, не так, как вы опубликовали.В URL должно быть что-то, что определяет культуру, что-то вроде:

В противном случае вы можете в конечном итогес неоднозначным URL между двумя или более языками / культурами.

...