每条路线的控制器工厂

发布于 2024-12-28 06:10:14 字数 475 浏览 2 评论 0原文

我已经实现了一个自定义路由(继承自 RouteBase),以根据数据库中存储的数据获得动态路由。处理后,该路由最终返回包含以下内容的 RouteData: 1) EF实体 2)行动 3)控制器

一切按预期工作,除了我希望控制器值是控制器的完整类型名称(我允许我的用户从管理面板中选择它)或单词“自动”。如果选择“自动”,我将使用结构图来定位实现通用 Controller的控制器。为此,我使用路由数据返回 MvcRouteHandler,并将自定义控制器工厂传递到其构造函数中。

经过一番挖掘后,我意识到 MvcRouteHandler 不会将该控制器工厂传递给它创建的 MvcHandler,因此我的自定义控制器工厂永远不会被调用,并且路由总是失败。 我不确定我有什么选择(如果有的话)。我想我可能可以设置一般的控制器工厂,但我觉得这是错误的,因为只有我的自定义路由处理的请求才应该具有自定义控制器工厂。

提前致谢, 约翰

I have implemented a custom route (inherit from RouteBase) to have dynamic routes based on the data stored in the database. After processing, this route ends up returning RouteData containing
1) An EF entity
2) action
3) controller

All works as expected except that I would like for the controller value to be either the full type name of a controller (I allow my users to select it from the admin panel) or the word 'Auto'. If Auto is selected I use structure map to locate a controller that implements a generic Controller<TEntityType>. To do this I return with the route data an MvcRouteHandler with a custom controller factory passed into it's constructor.

After a little digging I realized that the MvcRouteHandler does not pass that controller factory to the MvcHandler that it creates therefore my custom controller factory is never called and the route always fails.
I am not sure what alternatives I have if any. I think I could probably set the controller factory in general but I feel that that would be wrong as only the requests handled by my custom routes should have the custom controller factory.

Thanks in advance,
John

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请别遗忘我 2025-01-04 06:10:14

最终完成以下作品。唯一的灰点是框架未向其传递 RequestContext 的 ReleaseController 方法。但这没关系,因为该方法所做的只是在控制器上调用 dispose(如果它实现了 IDisposible),因此默认实现就可以了。

   public class RouteControllerFactory : IControllerFactory
{
    private readonly DefaultControllerFactory Default = new DefaultControllerFactory();

    public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        return (requestContext.RouteData.Values.TryGetValue("controllerfactory") as IControllerFactory ?? Default).CreateController(requestContext, controllerName);
    }

    public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        return (requestContext.RouteData.Values.TryGetValue("controllerfactory") as IControllerFactory ?? Default).GetControllerSessionBehavior(requestContext, controllerName);
    }

    public void ReleaseController(IController controller)
    {
        Default.ReleaseController(controller);
    }
}

要注册控制器工厂只需使用
ControllerBuilder.Current.SetControllerFactory(typeof(RouteControllerFactory));

在应用程序_开始

In the end the following works. The only gray point is the ReleaseController method to which the framework does not pass a RequestContext. This is ok though because all that method does is call dispose on the controller if it implements IDisposible so the default implementation is fine.

   public class RouteControllerFactory : IControllerFactory
{
    private readonly DefaultControllerFactory Default = new DefaultControllerFactory();

    public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        return (requestContext.RouteData.Values.TryGetValue("controllerfactory") as IControllerFactory ?? Default).CreateController(requestContext, controllerName);
    }

    public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        return (requestContext.RouteData.Values.TryGetValue("controllerfactory") as IControllerFactory ?? Default).GetControllerSessionBehavior(requestContext, controllerName);
    }

    public void ReleaseController(IController controller)
    {
        Default.ReleaseController(controller);
    }
}

To register the controller factory just use
ControllerBuilder.Current.SetControllerFactory(typeof(RouteControllerFactory));

at Application_Start

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文