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

Локализация/перевод маршрутов в ASP.NET MVC

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

Ответ 5

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

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(), и при необходимости вы можете изменить логику. Я рекомендую вам добавить кеширование, потому что это сделает каждый запрос попадающим в базу данных как есть. Таблица маршрутов заполняется при запуске приложения, но каждый маршрут выполняется по каждому запросу.

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