ASP.NET Страница MVC-URL и маршрутизация контроллера / действия

#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.

Проблема решена, окончательное решение:

  1. Добавление этих двух маршрутов:

     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()
    );
      
  2. Мой собственный обработчик маршрута:

     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