如何在 ASP.NET MVC 中实现动态控制器和动作方法? [英] How to achieve a dynamic controller and action method in ASP.NET MVC?

查看:33
本文介绍了如何在 ASP.NET MVC 中实现动态控制器和动作方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Asp.net MVC 中,url 结构类似于

In Asp.net MVC the url structure goes like

http://example.com/{controller}/{action}/{id}

http://example.com/{controller}/{action}/{id}

对于每个控制器",比如 http://example.com/blog,都有一个 BlogController.

For each "controller", say http://example.com/blog, there is a BlogController.

但是我的 url 的 {controller} 部分不是预先决定的,而是在运行时动态确定的,我如何创建一个动态控制器",将任何东西映射到同一个控制器,然后基于值并决定做什么?

But my {controller} portion of the url is not decided pre-hand, but it is dynamically determined at run time, how do I create a "dynamic controller" that maps anything to the same controller which then based on the value and determines what to do?

与 {action} 相同,如果我的 url 的 {action} 部分也是动态的,有没有办法对这种情况进行编程?

Same thing with {action}, if the {action} portion of my url is also dynamic, is there a way to program this scenario?

推荐答案

当然可以!如果自定义控制器不存在,您需要覆盖 DefaultControllerFactory 以查找自定义控制器.然后您需要编写一个 IActionInvoker 来处理动态操作名称.

Absolutely! You'll need to override the DefaultControllerFactory to find a custom controller if one doesn't exist. Then you'll need to write an IActionInvoker to handle dynamic action names.

您的控制器工厂看起来像:

Your controller factory will look something like:

public class DynamicControllerFactory : DefaultControllerFactory
{
    private readonly IServiceLocator _Locator;

    public DynamicControllerFactory(IServiceLocator locator)
    {
        _Locator = locator;
    }

    protected override Type GetControllerType(string controllerName)
    {
        var controllerType = base.GetControllerType(controllerName);
            // if a controller wasn't found with a matching name, return our dynamic controller
        return controllerType ?? typeof (DynamicController);
    }

    protected override IController GetControllerInstance(Type controllerType)
    {
        var controller = base.GetControllerInstance(controllerType) as Controller;

        var actionInvoker = _Locator.GetInstance<IActionInvoker>();
        if (actionInvoker != null)
        {
            controller.ActionInvoker = actionInvoker;
        }

        return controller;
    }
}

那么你的动作调用者应该是这样的:

Then your action invoker would be like:

public class DynamicActionInvoker : ControllerActionInvoker
{
    private readonly IServiceLocator _Locator;

    public DynamicActionInvoker(IServiceLocator locator)
    {
        _Locator = locator;
    }

    protected override ActionDescriptor FindAction(ControllerContext controllerContext,
                                                   ControllerDescriptor controllerDescriptor, string actionName)
    {
            // try to match an existing action name first
        var action = base.FindAction(controllerContext, controllerDescriptor, actionName);
        if (action != null)
        {
            return action;
        }

// @ray247 The remainder of this you'd probably write on your own...
        var actionFinders = _Locator.GetAllInstances<IFindAction>();
        if (actionFinders == null)
        {
            return null;
        }

        return actionFinders
            .Select(f => f.FindAction(controllerContext, controllerDescriptor, actionName))
            .Where(d => d != null)
            .FirstOrDefault();
    }
}

您可以在此处查看更多此代码.这是我自己和一位同事在编写完全动态的 MVC 管道时的旧初稿尝试.您可以随意将其用作参考并复制您想要的内容.

You can see a lot more of this code here. It's an old first draft attempt by myself and a coworker at writing a fully dynamic MVC pipeline. You're free to use it as a reference and copy what you want.

编辑

我想我应该包括一些关于该代码的作用的背景知识.我们试图围绕域模型动态构建 MVC 层.因此,如果您的域包含 Product 类,您可以导航到 productsalls 以查看所有产品的列表.如果要添加产品,请导航到 productadd.您可以转到 productedit1 来编辑产品.我们甚至尝试了诸如允许您编辑实体的属性之类的方法.所以 producteditprice1?value=42 会将产品 #1 的 price 属性设置为 42.(我的路径可能有点偏离,我已经记不起确切的语法了.)希望这有帮助!

I figured I should include some background about what that code does. We were trying to dynamically build the MVC layer around a domain model. So if your domain contained a Product class, you could navigate to productsalls to see a list of all products. If you wanted to add a product, you'd navigate to productadd. You could go to productedit1 to edit a product. We even tried things like allowing you to edit properties on an entity. So producteditprice1?value=42 would set the price property of product #1 to 42. (My paths might be a little off, I can't recall the exact syntax anymore.) Hope this helps!

这篇关于如何在 ASP.NET MVC 中实现动态控制器和动作方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆