Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 基于存储在数据库中的URL的自定义MVC路由_Asp.net Mvc 3_Routing - Fatal编程技术网

Asp.net mvc 3 基于存储在数据库中的URL的自定义MVC路由

Asp.net mvc 3 基于存储在数据库中的URL的自定义MVC路由,asp.net-mvc-3,routing,Asp.net Mvc 3,Routing,我正试图根据存储在mvc数据库中的url添加一些自定义路由逻辑。(CMS-Like),我认为它相当基本,但我觉得我没有真正取得任何进展 基本上,用户可以键入url,例如: www.somesite.com/categorya/categoryb/categoryf/someitem www.somesite.com/about/someinfo 在数据库中,这些项目与它们的类型一起存储,即普通页面或产品页面 根据这一点,我想实际使用一种不同的“动作”方法,即,我想使用上述方法: PageCon

我正试图根据存储在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
现在我一直在看这里:

并试图以此为基础,但我实际上如何在InvokeActionMethod调用中“更改”我想要命中的操作方法

使用MVC3.0 btw

谢谢你的帮助/建议

最终解决方案:

Global.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);
        }
    }

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

我所做的是在Global.asax中设置一个简单的路由,并使用一个调用自定义RouteHandler类的catch all参数

// 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);
    }
}
公共类应用程序RouteHandler:IRoutHandler
{
/// 
///提供处理请求的对象。
/// 
///封装有关请求的信息的对象。
/// 
///处理请求的对象。
/// 
公共IHttpHandler GetHttpHandler(RequestContext RequestContext)
{
字符串路径=requestContext.RouteData.Values[“path”]作为字符串;
//尝试检索当前路径的控制器和操作
页面=GetPageData(路径);
//方法返回404错误
如果(第==null页)
返回SetupErrorHandler(requestContext,“ApplicationRouteHandler”);
//将路由值分配给当前requestContext
requestContext.RouteData.Values[“controller”]=page.controller;
requestContext.RouteData.Values[“action”]=page.action;
返回新的MvcHandler(requestContext);
}
}

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

这就是我迄今为止所做的,我将添加一些代码来显示我的位置,这正是我需要的,谢谢!我知道这是一件相当琐碎的事情,但我找不到任何像样的例子!假设今天结束时没有“更好”的方法,我会接受这一点作为奖励:)轻微的打嗝,为了确定我需要的“操作”,我需要使用会话,该会话当前设置为null,基本上在调用global.asax中的session_开始之前,处理程序被命中,难道你没有遇到类似的问题吗?你正在从
requestContext.HttpContext.Session
获取
null
?我认为它可以为null的唯一方法是如果它没有存储任何内容。在GetHttpHandler方法之后会命中Session_Start,但我认为我们只需要按照当前使用Session的方式重新工作。你是对的,我只是假设Session在那一点上是可用的,但它不是。您可以尝试实施此问题中的解决方案(尚未尝试,因此我不知道……):