asp.net mvc. Routing and Url building

无人久伴 提交于 2019-12-03 09:00:24
Cristi Pufu

This will help:

ASP.NET mvc, localized routes and the default language for the user

asp.net mvc localization

Set Culture in an ASP.Net MVC app

You have to register two routes:

routes.MapRoute(
            name: "DefaultLang",
            url: "{language}/{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            constraints: new { language = "[a-z]{2}"}
        );

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

Create an Attribute that inherits ActionFilterAttribute:

public class LanguageActionFilterAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var routeDataKey = "language";
            var defaultLang = "en";
            var defaultCulture = "EN";

            // if no language route param received
            if (filterContext.RouteData.Values[routeDataKey] == null /* && currentCulture != "en-EN" */)
            {
                // change culture to en-EN
                Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", defaultLang, defaultCulture));
                Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", defaultLang, defaultCulture));
            }
            else
            {
                 /*if (currentCulture != "whatever")
                 { 
                    //set culture to whatever
                 }*/
            }

            base.OnActionExecuting(filterContext);
        }
    }

After that create a BaseController with the previous created attribute:

[LanguageActionFilter]
public abstract class BaseController : Controller
{

}

And all your Controllers will inherit BaseController now, instead of Controller

The following RouteConstraint might help,

public class CultureConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
                      RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.UrlGeneration)
        {
            return values[parameterName] != null &&
                   (route.Defaults[parameterName] == null ||
                    values[parameterName].ToString().ToLower() != route.Defaults[parameterName].ToString().ToLower());
        }
        return true;
    }
}

Use it as,

routes.MapRoute(
    name: "Culture",
    url: "{culture}/{controller}/{action}/{id}",
    defaults: new {culture = "en", controller = "Home", action = "Index", id = UrlParameter.Optional},
    constraints: new {culture = new CultureConstraint()}
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);

Here the constraint only works on outbound url and discard the route for candidacy when 'culture' in route information equals to default.

I used the simplest implementation because you have not posted your route code, but the idea should work.

hope this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!