Dresel / RouteLocalization

RouteLocalization is an MVC and Web API package that allows localization of your attribute routes.
MIT License
67 stars 13 forks source link

Resolving routing provided that incorrect pairs locale - localisation #53

Closed manst closed 7 years ago

manst commented 9 years ago

Hello, In RouteLocalization.Mvc.Sample

/en/Welcome => culture: en, Contoller: Home, Action: Index /de/Willkommen => culture: de, Contoller: Home, Action: Index /en/Willkommen => 404 /de/Welcome => 404

Сan I made to work if incorrect pairs locale - localisation: /en/Willkommen => culture: en, Contoller: Home, Action: Index /de/Welcome => culture: de, Contoller: Home, Action: Index

Thank You, Yuriy

Dresel commented 9 years ago

Hi,

it is not really supported, but you can do it like this:

Since RouteLocalization does not add the culture as parameter (its a fixed string), you would have to disable AddCultureAsRoutePrefix:

configuration.AddCultureAsRoutePrefix = false;

Then add the culture parameter manually to the route:

[RoutePrefix("{culture}")]
public partial class HomeController : Controller
{

And create your own culture detection filter:

public class CustomFilter : CultureSensitiveActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // Check for RouteData
        if (context.RouteData.Values["culture"] == null)
        {
            return;
        }

        // Get RouteData
        string cultureName = (string)context.RouteData.Values["culture"];

        // Set culture
        CultureInfo cultureInfo = new CultureInfo(cultureName);

        // Try to override to region dependent browser culture
        if (TryToPreserverBrowserRegionCulture)
        {
            if (AcceptedCultures.Count == 0)
            {
                throw new InvalidOperationException("TryToPreserverBrowserRegionCulture can only be used in combination with AcceptedCultures.");
            }

            cultureInfo =
                Localization.DetectCultureFromBrowserUserLanguages(
                    new HashSet<string>(AcceptedCultures.Where(culture => culture.StartsWith(cultureInfo.Name))), cultureInfo.Name)(
                        context.HttpContext.ApplicationInstance.Context);
        }

        if (SetCurrentCulture)
        {
            Thread.CurrentThread.CurrentCulture = cultureInfo;
        }

        if (SetCurrentUICulture)
        {
            Thread.CurrentThread.CurrentUICulture = cultureInfo;
        }
    }
}

Which you can then use like the original one:

GlobalFilters.Filters.Add(new CustomFilter()
{
    // Set this options only if you want to support detection of region dependent cultures
    // Supports this use case: https://github.com/Dresel/RouteLocalization/issues/38#issuecomment-70999613
    AcceptedCultures = acceptedCultures,
    TryToPreserverBrowserRegionCulture = true
});

Hope that helps.