修改MVC项目,以定位控制器在我的功能基于自定义路径

本文关键字:功能 我的 路径 自定义 控制器 项目 MVC 定位 修改 | 更新日期: 2023-09-27 18:14:47

我正在做一个ASP。. NET MVC 5项目,我想应用Jimmy Bogard的"功能驱动设计",在这篇文章中显示。但我想修改他的设计,将功能按角色划分为另一个子部门,所以我的计划是让我的ASP。. NET MVC项目:

MyRoleFeatureProject ├── Roles │ ├── Manager │ │ ├── Features │ │ │ ├── Index │ │ │ │ ├── Index.cshtml │ │ │ │ ├── Index.js │ │ │ │ ├── IndexController.cs │ │ │ ├── Invoice │ │ │ │ ├── Invoice.cshtml │ │ │ │ ├── Invoice.js │ │ │ │ ├── InvoiceController.cs │ ├── Admin │ │ ├── Features │ │ │ ├── Index │ │ │ │ ├── Index.cshtml │ │ │ │ ├── Index.js │ │ │ │ ├── IndexController.cs │ │ │ ├── UserManagement │ │ │ │ ├── UserManagement.cshtml │ │ │ │ ├── UserManagement.js │ │ │ │ ├── UserManagementController.cs │ ├── Operator │ │ ├── Features │ │ │ ├── Index │ │ │ │ ├── Index.cshtml │ │ │ │ ├── Index.js │ │ │ │ ├── IndexController.cs │ │ │ ├── Shipping │ │ │ │ ├── Shipping.cshtml │ │ │ │ ├── Shipping.js │ │ │ │ ├── ShippingController.cs │ ├── Anonymous │ │ ├── Features │ │ │ ├── LogIn │ │ │ │ ├── LogIn.cshtml │ │ │ │ ├── LogIn.js │ │ │ │ ├── LogInController.cs │ │ │ ├── Register │ │ │ │ ├── Register.cshtml │ │ │ │ ├── Register.js │ │ │ │ ├── RegisterController.cs │ │ │ ├── ForgotPassword │ │ │ │ ├── ForgotPassword.cshtml │ │ │ │ ├── ForgotPassword.js │ │ │ │ ├── ForgotPasswordController.cs │ ├── Shared │ │ ├── _ManagerLayout.cshtml │ │ ├── _AdminLayout.cshtml │ │ ├── _OperatorLayout.cshtml │ │ ├── _AnonymousLayout.cshtml │ ├── _ViewStart.cshtml │ ├── Web.config ├── Images ├── Scripts ├── Styles ├── Web.config

我遵循了一些在线指南,我明白我需要创建一个继承自DefaultControllerFactory控制器的自定义位置的类,还有一个继承自RazorViewEngine视图的自定义位置的类,但我无法配置它们以匹配我在树形图中向您展示的位置,这就是为什么我请求您的帮助。

我不是ASP专家。这是我在学习新事物的过程中第一次尝试实现这种设计。我真的很想让它工作起来。

谢谢你的指导。

更新1

在看到@IvanGritsenko的回答后,我注意到每个控制器必须能够处理多个动作(对于该功能),并且许多角色可以具有相同名称的功能(控制器),例如"索引",每个角色将有一个索引,这将是一个自定义的"仪表板"(显示自定义信息的角色)。

考虑到这一点,我认为如果:

1)通过某种方式,我可以在用户登录后解析控制器的位置。如果我查找索引控制器它可以在特定的角色文件夹中查找。

2)用户登录后修改路由以匹配模式/角色/控制器/特征

修改MVC项目,以定位控制器在我的功能基于自定义路径

步骤1。创建自定义视图引擎

public class MyViewEngine : RazorViewEngine 
{
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        var roleName = controllerContext.RouteData.GetRequiredString("role");
        var controllerName = controllerContext.RouteData.GetRequiredString("controller");
        var path = string.Format("~/Roles/{0}/Features/{1}/{1}.cshtml", roleName, controllerName);
        var layoutPath = string.Format("/Roles/Shared/_{0}Layout.cshtml", controllerName);
        return new ViewEngineResult(new RazorView(controllerContext, path, layoutPath, false, null), this);
    }
    public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
    {
        var roleName = controllerContext.RouteData.GetRequiredString("role");
        var controllerName = controllerContext.RouteData.GetRequiredString("controller");
        var path = string.Format("~/Roles/{0}/Features/{1}/{1}.cshtml", roleName, controllerName);
        return new ViewEngineResult(new RazorView(controllerContext, path, null, false, null), this);
    }
}

步骤2。在Global.asax.

中注册自定义视图引擎
protected void Application_Start()
{
    ...
    ViewEngines.Engines.Add(new MyViewEngine());
}

步骤3。修改RouteConfig

默认路由
routes.MapRoute( name: "Default", url: "{role}/{controller}", defaults: new { action = "Index" });

控制器

示例
public class UserManagementController : Controller
{
    // GET: UserManagement
    public ActionResult Index()
    {
        return View();
    }
}

url调用UserManagementControllerIndex动作示例

http://domainname.com/Admin/UserManagement