Префиксная маршрутизация в ASP.Net MVC наподобие cakephp - PullRequest
1 голос
/ 24 августа 2009

Я хотел бы узнать, как настроить маршрутизацию с префиксом, как это есть в cakephp для маршрутизации администратора. К сожалению, я не понял, как это сделать в ASP.NET MVC.

Например,

Если пользователь вводит / Admin / Management, я бы хотел, чтобы вызывался контроллер Management.admin_index без изменения URL-адреса. Я попробовал то, что мне показалось правильным, но в итоге все мои URL были изменены.

Итак, вопрос: если это возможно, как мне выполнить префиксную маршрутизацию в ASP.NET MVC?

Обновление: это именно то, что я искал. http://devlicio.us/blogs/billy_mccafferty/archive/2009/01/22/mvc-quot-areas-quot-as-hierarchical-subfolders-under-views.aspx Этот код позволяет вам иметь веб-сайт по умолчанию, а затем область администратора.

Ответы [ 3 ]

2 голосов
/ 24 августа 2009

Может быть, вам стоит попробовать написать собственный маршрут. Посмотрите на System.Web.Routing.RouteBase.

* редактировать *

Хорошо, у меня был другой взгляд, и я был неправ. То, что изначально было моей первой мыслью, оказалось более простым решением: вы должны реализовать собственный IRouteHandler, например:

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace PrefixRoutingTest.Util
{
    public class PrefixRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            //only apply this behavior to a part of the site
            if (requestContext.HttpContext.Request.Path.ToLower().StartsWith("/prefixed/") &&
                requestContext.HttpContext.User.Identity.IsAuthenticated)
            {
                //prefix the action name with Admin
                var action = requestContext.RouteData.Values["action"].ToString();
                requestContext.RouteData.Values["action"] = "Admin" + action;
            }

            return new MvcHandler(requestContext);
        }
    }
}

Затем создайте контроллер с двумя действиями, добавьте к одному из них префикс «Admin» и пометьте его атрибутом AuthorizeAttribute. Это должно выглядеть примерно так:

using System.Web.Mvc;

namespace PrefixRoutingTest.Controllers
{
    public class PrefixedController : Controller
    {
        public ActionResult Test()
        {
            return View();
        }

        [Authorize]
        public ActionResult AdminTest()
        {
            return View();
        }

    }
}

Создайте папку «Prefixed» в папке Views и добавьте в нее два Views: Test.aspx и AdminTest.aspx. Тогда вам просто нужно заменить маршрут по умолчанию (в Global.asax) следующим кодом:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add("Default", new Route("{controller}/{action}/{id}", new PrefixRouteHandler())
    {
        Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" })
    });
}

И все, теперь, когда вы переходите на сайт / с префиксом / тестировать как анонимный пользователь, вы должны получить стандартное представление Тест, но если вы являетесь администратором, вы получите представление AdminTest. Однако если анонимный пользователь попытается получить прямой доступ к URL AdminTest, он будет отправлен на страницу входа в систему.

PS: Я могу подтвердить, что это работает, так что, если у вас есть проблемы с его реализацией, просто позвоните мне;)

0 голосов
/ 14 октября 2009

Я тоже искал, как это сделать, и только что понял.

Вот код в VB (его не должно быть сложно перевести на c #)


Создать класс, реализующий IRouteHandler:

Imports System.Web
Imports System.Web.Mvc
Imports System.Web.Routing

Namespace Util.Routing
    ''' <summary>
    ''' This Route Handler looks for a 'prefix' part in the url. If found, it appends the prefix to the action name.
    ''' Example: /prefix/controller/action
    '''   Turns into: /controller/prefix_action
    ''' </summary>
    ''' <remarks></remarks>
    Public Class PrefixRouteHandler
        Implements IRouteHandler

        Public Function GetHttpHandler(ByVal requestContext As System.Web.Routing.RequestContext) As System.Web.IHttpHandler Implements System.Web.Routing.IRouteHandler.GetHttpHandler
            Dim prefix = requestContext.RouteData.Values("prefix")
            If (prefix IsNot Nothing) Then
                ' If prefix actually exists in the beginning of the URL
                If (requestContext.HttpContext.Request.Path.ToLower().StartsWith("/" & prefix.ToString.ToLower() & "/")) Then
                    Dim action = requestContext.RouteData.Values("action")
                    If action Is Nothing Then
                        action = "index"
                    End If
                    requestContext.RouteData.Values("action") = prefix & "_" & action
                End If
            End If
            Return New MvcHandler(requestContext)
        End Function
    End Class
End Namespace

Затем добавьте это в ваш global.asax.vb:

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
    routes.IgnoreRoute("{*favicon}", New With {.favicon = "(.*/)?favicon.ico(/.*)?"})
    routes.IgnoreRoute("{resource}.aspx/{*pathInfo}")
    ' MapRoute takes the following parameters, in order:
    ' (1) Route name
    ' (2) URL with parameters
    ' (3) Parameter defaults
    routes.Add(New Route("admin/{controller}/{action}/{id}", _
                    New RouteValueDictionary(New With {.prefix = "Admin", .controller = "Home", .action = "Index", .id = ""}), _
                    New PrefixRouteHandler() _
               ) _
    )
    routes.Add(New Route("manager/{controller}/{action}/{id}", _
                    New RouteValueDictionary(New With {.prefix = "Manager", .controller = "Home", .action = "Index", .id = ""}), _
                    New PrefixRouteHandler() _
               ) _
    )
    routes.MapRoute("Default", _
        "{controller}/{action}/{id}", _
        New With {.controller = "Home", .action = "Index", .id = ""} _
    )

End Sub

Вы заметите, что есть два префиксных маршрута: admin / controller / action и manager / controller / action. Вы можете добавить столько, сколько хотите.

- Edit-- Первоначально это работало, пока я не попытался использовать Html.Actionlink для создания ссылок. Это заставляет ActionLink добавлять admin / к каждому сгенерированному URL. Итак, я исправил это. Это должно привести к тому, что префиксная маршрутизация будет работать так же, как и административная маршрутизация CakePHP.

вот редактирование:

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
    routes.IgnoreRoute("{*favicon}", New With {.favicon = "(.*/)?favicon.ico(/.*)?"})
    routes.IgnoreRoute("{resource}.aspx/{*pathInfo}")

    routes.Add("AdminPrefix", _
                    New Route("{prefix}/{controller}/{action}/{id}", _
                    New RouteValueDictionary(New With {.controller = "Home", .action = "Index", .id = "", .prefix = ""}), _
                    New RouteValueDictionary(New With {.prefix = "admin"}), _
                    New PrefixRouteHandler()))
    routes.Add("ManagerPrefix", _
                    New Route("{prefix}/{controller}/{action}/{id}", _
                    New RouteValueDictionary(New With {.controller = "Home", .action = "Index", .id = "", .prefix = ""}), _
                    New RouteValueDictionary(New With {.prefix = "manager"}), _
                    New PrefixRouteHandler()))
    routes.MapRoute("Default", _
        "{controller}/{action}/{id}", _
        New With {.controller = "Home", .action = "Index", .id = ""} _
    )

End Sub
0 голосов
/ 24 августа 2009

Я думаю, может быть, установить маршрут для него?

В этом примере вам потребуется создать маршрут для каждого (администратора) контроллера.

routes.MapRoute(null,
    "Admin/{controller}/{action}/",
    new { controller = "Management", action = "Index" });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...