asp.net mvc. Routing and Url building

蹲街弑〆低调 提交于 2020-01-12 06:19:06

问题


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?


回答1:


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




回答2:


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.



来源:https://stackoverflow.com/questions/16103621/asp-net-mvc-routing-and-url-building

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