MVC 排除控制器使用

Yan*_*Yan 2 c# asp.net-mvc inheritance routing overriding

我创建了一个“模板”项目 A,它有 10 个控制器(部分类)。所有这些控制器都打包在一个 nuget 包中,供项目 B、C 和 D 使用。nuget 在文件夹中生成控制器,controllers/_core因此它们很好地分开存储。该NuGet包并没有必须就A项目的DLL的引用

现在开始解决问题; 可能需要修改生成的控制器之一。通过添加第二个部分,我们可以添加一些逻辑,但可能需要覆盖现有方法以在方法内添加逻辑。正因为如此(也因为我在下面添加的原因),我想从这些基本控制器继承。当我们继承一个基本控制器时,它应该被 MVC 排除。

示例:Image PersonController 是通过使用 nuget 包在 controller/_core 文件夹中创建的,并且每个方法都是虚拟的。然后,我们将_PersonController在从 PersonController 继承的控制器文件夹中创建一个,为简单起见,仅覆盖 index 方法。这时候我们想改变路由,让 localhost/Person/index 最终出现在 的 index 方法中,_PersonController而不是PersonController. PersonController应该完全忽略。

每次我们需要覆盖时,我唯一的选择是添加自定义路由吗?或者对于这类问题有更好的解决方案(自定义 MVC 控制器工厂?)?+ 我如何定义这样的路由?

我想继承的额外原因: 每次我们更新 nuget 包时,它都会尝试覆盖对消费者项目 B、C 和 D 中生成的控制器所做的所有更改。

亲切的问候,

雅尼克

Alb*_*rtK 5

您可以使用控制器继承。

ASP.NET 核心

要忽略不必要的控制器,您需要实现IApplicationFeatureProvider<ControllerFeature>或派生自ControllerFeatureProvider

public class MyControllerFeatureProvider : ControllerFeatureProvider
{
    protected override bool IsController(TypeInfo typeInfo)
    {
        var isController = base.IsController(typeInfo);
        if (isController)
        {
            //overriding isController value
        }
        return isController;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您Starup.ConfigureServices需要替换默认值ControllerFeatureProvider

services.AddMvc()
.ConfigureApplicationPartManager(manager =>
{
    var controllerFeatureProvider =
        manager.FeatureProviders
            .Single(p => p.GetType() == typeof(Microsoft.AspNetCore.Mvc.Controllers.ControllerFeatureProvider));
    manager.FeatureProviders[manager.FeatureProviders.IndexOf(controllerFeatureProvider)] =
       new Attributes.MyControllerFeatureProvider();
});
Run Code Online (Sandbox Code Playgroud)

ASP.NET MVC 5 及更早版本

在您的特定情况下,你可以去航线上注册的名称空间列表和设置UseNamespaceFallback,以false忽略其他命名空间:

var myRoute  = routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
        namespaces: new [] {"Namespace1", "Namespace2"}
    );

myRoute.DataTokens["UseNamespaceFallback"] = false;
Run Code Online (Sandbox Code Playgroud)