3

我正在尝试根据存储在 mvc 数据库中的 url 添加一些自定义路由逻辑。(CMS Like),我认为它相当基本,但我觉得我并没有真正到达任何地方。

基本上,用户可以键入 url,例如:

www.somesite.com/categorya/categoryb/categoryf/someitem
www.somesite.com/about/someinfo

在数据库中存储这些项目以及它们的类型,即普通页面或产品页面。

根据这一点,然后我想实际使用不同的“动作”方法,即我希望上面的方法可以使用:

PageController/Product
PageController/Normal

然后,这些操作会加载此页面的内容并显示相同的视图(产品视图或普通视图)。

使用正常的路由方式是行不通的,因为我可能有类似的东西;

cata/producta
cata/catb/catc/catd/cate/catf/producta

现在我一直在看这里:ASP.NET MVC custom routing for search

并试图以此为基础,但我如何真正“改变”我想在 InvokeActionMethod 调用中点击的操作方法?

顺便说一句,使用 MVC 3.0。

感谢您的任何帮助/建议

最终解决方案:

全球.asax

routes.MapRoute(
                "Default",
                "{*path}",
                new { controller = "Page", action = "NotFound", path= "Home" }
            ).RouteHandler = new ApplicationRouteHandler();

路由处理程序

public class ApplicationRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new ApplicationHandler(requestContext);
        }
    }

    public class ApplicationHandler : MvcHandler, IRequiresSessionState
    {
        public ApplicationHandler(RequestContext requestContext)
            : base(requestContext)
        {

        }

        protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            var url = RequestContext.RouteData.Values["path"].ToString();
            var page = SomePageService.GetPageByUrl(url);

            if (page == null)
            {
                RequestContext.RouteData.Values["Action"] = "NotFound";
            }
            else
            {
                RequestContext.RouteData.Values["Action"] = page.Action;
                RequestContext.RouteData.Values["page"] = page;
            }

            return base.BeginProcessRequest(httpContext, callback, state);
        }
    }
4

1 回答 1

4

对于您的情况,也许不是一个确切的解决方案,但我最近不得不处理类似的事情,所以这可能会为您指明正确的方向。

我所做的是在 Global.asax 中设置一个简单的路由,其中​​包含一个调用自定义 RouteHandler 类的包罗万象的参数。

// Custom MVC route
routes.MapRoute(
    "Custom",
    "{lang}/{*path}",
    new { controller = "Default", action = "Index" },
    new { lang = @"fr|en" }
).RouteHandler = new ApplicationRouteHandler();

ApplicationRouteHandler.cs :

public class ApplicationRouteHandler : IRouteHandler
{
    /// <summary>
    /// Provides the object that processes the request.
    /// </summary>
    /// <param name="requestContext">An object that encapsulates information about the request.</param>
    /// <returns>
    /// An object that processes the request.
    /// </returns>
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string path = requestContext.RouteData.Values["path"] as string;
    // attempt to retrieve controller and action for current path
        Page page = GetPageData(path);

    // Method that returns a 404 error
        if (page == null)
            return SetupErrorHandler(requestContext, "ApplicationRouteHandler");

    // Assign route values to current requestContext
        requestContext.RouteData.Values["controller"] = page.Controller;
        requestContext.RouteData.Values["action"] = page.Action;
        return new MvcHandler(requestContext);
    }
}

显然,您从数据库中检索动作和控制器名称的方式可能与我的大不相同,但这应该会给您一个想法。

于 2012-08-27T14:01:08.540 回答