#c# #asp.net #asp.net-mvc #asp.net-mvc-routing
#c# #asp.net #asp.net-mvc #asp.net-mvc-routing
Вопрос:
У меня проблемы с созданием ASP.NET Страница MVC, которая допускает два вида маршрутизации.
У меня есть база данных, в которой все страницы хранятся с URL-путем, например: /Site1/Site2/Site3 я попытался использовать IRouteConstraint в моем первом маршруте, чтобы проверить, является ли запрошенный сайт сайтом из моей базы данных (постоянная ссылка).
Во втором случае я хочу использовать значение по умолчанию asp.net функциональность mvc {controller} / {action} для обеспечения простого доступа из *.cshtml.
Теперь я не знаю, лучший ли это способ. Кроме того, у меня проблема, как выполнить root с помощью IRouteContraint.
У кого-нибудь есть опыт работы с этим?
Я использую asp.net mvc 5.
Проблема решена, окончательное решение:
-
Добавление этих двух маршрутов:
routes.MapRoute( "FriendlyUrlRoute", "{*FriendlyUrl}" ).RouteHandler = new FriendlyUrlRouteHandler(); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Page", action = "Load", id = UrlParameter.Optional }, namespaces: controllerNamespaces.ToArray() );
-
Мой собственный обработчик маршрута:
public class FriendlyUrlRouteHandler : System.Web.Mvc.MvcRouteHandler { protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext) { var friendlyUrl = (string)requestContext.RouteData.Values["FriendlyUrl"]; WebPageObject page = null; if (!string.IsNullOrEmpty(friendlyUrl)) { page = PageManager.Singleton.GetPage(friendlyUrl); } if (page == null) { page = PageManager.Singleton.GetStartPage(); } // Request valid Controller and Action-Name string controllerName = String.IsNullOrEmpty(page.ControllerName) ? "Page" : page.ControllerName; string actionName = String.IsNullOrEmpty(page.ActionName) ? "Load" : page.ActionName; requestContext.RouteData.Values["controller"] = controllerName; requestContext.RouteData.Values["action"] = actionName; requestContext.RouteData.Values["id"] = page; return base.GetHttpHandler(requestContext); } }
Ответ №1:
Вы можете использовать атрибутивную маршрутизацию, которая находится в MVC 5, и комбинировать атрибутивную маршрутизацию с маршрутизацией на основе соглашений, чтобы проверить условие, которое вы хотите для класса контроллера или методов действия.
И вы могли бы сами установить ограничение, чтобы использовать его в методах действий, подобных этому:
public class ValuesConstraint : IRouteConstraint
{
private readonly string[] validOptions;
public ValuesConstraint(string options)
{
validOptions = options.Split('|');
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
object value;
if (values.TryGetValue(parameterName, out value) amp;amp; value != null)
{
return validOptions.Contains(value.ToString(), StringComparer.OrdinalIgnoreCase);
}
return false;
}
}
Чтобы использовать маршрутизацию атрибутов, вам просто нужно вызвать MapMvcAttributeRoutes
во время настройки и вызвать обычную маршрутизацию соглашения впоследствии. также вы должны добавить свое ограничение перед отображением атрибутов, как в приведенном ниже коде:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var constraintsResolver = new DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("values", typeof(ValuesConstraint));
routes.MapMvcAttributeRoutes(constraintsResolver);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Теперь в вашем классе контроллера вы можете проверить маршрут и решить, что делать с разными URL-адресами, как показано ниже:
например: // /mysite/Site1 и /mysite/Site2, но не /mysite/Site3
[Route("mysite/{site:values(Site1|Site2)}")]
public ActionResult Show(string site)
{
return Content("from my database " site);
}
И вы также можете выполнять все виды проверки только для вашего класса контроллера.
Я надеюсь, что это даст вам немного подсказки для достижения того, чего вы хотите.
Комментарии:
1. Спасибо, но когда я использую атрибутивную маршрутизацию, как я могу обрабатывать динамические маршруты, которые хранятся в моей базе данных?
2. Вы можете получить значение маршрута в классе ValuesConstraint из своей базы данных и написать соглашение, соответствующее вашим потребностям, а затем применить его к вашим методам действий в вашем классе контроллера.
3. Я нашел идеальное решение своей проблемы: URL-адреса, удобные для поисковой системы, в ASP.NET MVC с использованием динамической маршрутизации и базы данных SQL Server