ASP.net маршрутизация MVC с дополнительным первым параметром
мне нужно предоставить следующие возможности для одного из веб-сайтов.
http://www.example.com/[sponsor]/{controller}/{action}
в зависимости от [спонсор], веб-страница должна быть настроена.
я попробовал комбинацию регистрации маршрутов с Application_Start и Session_Start, но не смог заставить ее работать.
public static void RegisterRoutes(RouteCollection routes, string sponsor)
{
if (routes[sponsor] == null)
{
routes.MapRoute(
sponsor, // Route name
sponsor + "/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
}
кроме того, поведение по умолчанию без [спонсор] должны также функция. Может кто-нибудь, пожалуйста, дайте мне знать, если технически возможно иметь дополнительный первый параметр в URL MVC3. Если да, пожалуйста, поделитесь реализации. Спасибо.
Обновленный Код После внесения изменений, предложенных Сергей Кудрявцев, код работает, когда стоимости дают. Если имя не указано, то MVC не маршрутизирует к контроллеру / действию.
обратите внимание, что это работает только для контроллера Home (оба и не являются спонсорами). Для других контроллеров / действий, даже если указан параметр спонсора, это не маршрутизация.
пожалуйста, предложите, что должно быть изменено.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"SponsorRoute",
"{sponsor}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"NonSponsorRoute",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional, sponsor = string.Empty }
);
}
Способ Действий
public ActionResult Index(string sponsor)
{
}
4 ответов
в вашем случае sponsor
следует рассматривать не как постоянную часть URL, а как переменную часть.
В Глобальном.асакс:
public static void RegisterRoutes(RouteCollection routes)
{
...
routes.MapRoute(
"SponsorRoute",
"{sponsor}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
"NonSponsorRoute",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional, sponsor=string.Empty }
);
...
}
в ваших контроллерах, например, HomeController.cs:
namespace YourWebApp.Controllers
{
public class HomeController : Controller
{
public ActionResult Index(string sponsor)
{
// Here you can do any pre-processing depending on sponsor value, including redirects etc.
}
...
}
}
обратите внимание, что тип этого параметра всегда будет System.String
и имя компонента шаблона маршрута {sponsor}
должно точно соответствовать имени параметра action string sponsor
в своих контроллерах.
UPD: добавлен второй маршрут для не-спонсора случай.
обратите внимание, что такая настройка усложнит вашу логику, потому что вы можете спутать разные URL, например URL
может совпадать по обоим маршрутам: первый будет иметь sponsor=a, controller=b и action=c; второй будет иметь controller=a, action=b и id=c.
этой ситуации можно избежать, если вы укажете более строгие требования к URL-адресам - например, вы можете захотеть, чтобы идентификаторы были только численное. Ограничения указаны в четвертом параметре
в моем случае, я решил эту проблему с помощью следующих маршрутизаторов:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "MultiCulture",
url: "{culture}/{controller}/{action}",
defaults: new { controller = "Home", action = "Index" },
constraints: new { culture = new CultureConstraint(CultureFactory.All.Select(item => item.UrlPrefix).ToArray()) }
).RouteHandler = new MultiCultureMvcRouteHandler();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
}
}
здесь CultureConstraint
класс выглядит следующим образом:
public class CultureConstraint : IRouteConstraint
{
private readonly string[] values;
public CultureConstraint(params string[] values)
{
this.values = values;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary routeValues, RouteDirection routeDirection)
{
string value = routeValues[parameterName].ToString();
return this.values.Contains(value);
}
}
и MultiCultureMvcRouteHandler
такой:
public class MultiCultureMvcRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
{
var culture = CultureManager.GetCulture(requestContext.RouteData);
if (culture != null)
{
var cultureInfo = new CultureInfo(culture.Name);
Thread.CurrentThread.CurrentUICulture = cultureInfo;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureInfo.Name);
}
return base.GetHttpHandler(requestContext);
}
}
в дополнение к добавлению второго маршрута перед маршрутом по умолчанию, как сказал Сергей в своем ответе, вы также должны добавить RouteConstraint
на начальный маршрут, чтобы обеспечить, чтобы {sponsor}
token - это имя действительного спонсора.
Вы можете использовать RouteConstraint в этом ответе:Asp.Net пользовательская Маршрутизация и пользовательская маршрутизация и добавление категории перед контроллером
помните, что вы должны также применить правило, что имя спонсора не может быть таким же, как любой из ваших имена контроллеров.
Я покажу вам в простом примере, что вам не нужно меняться в маршрут.конфиг.cs только вы должны сделать в маршрут.конфиг.cs просто введите
необязательные параметры URI сначала и по умолчанию Значения
маршрут.конфиг.cs
routes.MapMvcAttributeRoutes();
контроллер
[Route("{Name}/Controller/ActionName")]
public ActionResult Details(string Name)
{
// some code here
return View();
}
результаты
localhost: 2345 / Name / controllername/actionname / id(необязательно)