asp.net mvc. Routing and Url building

2019-03-22 04:24发布

Does any body knows how to hide some parameters in url?

For example you have a url parameter "culture". It can be "en, fr, it". By default your site renders in "en" culture and we don't wont to show default culture in the URL but in cases of other cultures parameter "culture" must appear in URL.

http://myrendersite.net/barbikueue
http://myrendersite.net/fr/barbikueue

This is same pages in different cultures. How to do what basing on default asp.net mvc routing system?

2条回答
手持菜刀,她持情操
2楼-- · 2019-03-22 04:51

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

查看更多
我命由我不由天
3楼-- · 2019-03-22 04:59

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.

查看更多
登录 后发表回答