在运行时禁用 OData V4 元数据和控制器

Disabling OData V4 meta data and controllers at runtime

我们的软件中有多个模块作为单个产品提供。当一个模块被激活时,这些功能就可用了。我们希望我们的 OData API 遵循相同的模式。但是我不知道如何让 $metadata 忽略已禁用模块的控制器。基本上我想确定什么是随时可用的,而不是应用程序启动时间。

我们使用以下类型的鳕鱼来注册路线:

    static public void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<Module1Entity>("Module1Entities");
        builder.EntitySet<Module2Entity>("Module2Entities");
        config.MapODataServiceRoute("odata", "api", builder.GetEdmModel());
    }

    protected void Application_Start(object sender, EventArgs e)
    {
        GlobalConfiguration.Configure(Register);
    }

因此,如果模块已激活,我们只希望 Module1Entity 显示在元数据中。我们已经有了在模块停用时禁用关联控制器的代码。

有什么想法吗?

我最终找到了解决方案:

static public void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    var builder = new ODataConventionModelBuilder();
    if (IsModule1Enabled)
    {
        builder.EntitySet<Module1Entity>("Module1Entities");
    {
    if (IsModule2Enabled)
    {
       builder.EntitySet<Module2Entity>("Module2Entities");
    }
    var conventions = ODataRoutingConventions.CreateDefault();
    conventions.Insert(0, new MyAttributeRoutingConvention("odata", config));
    config.MapODataServiceRoute("odata", "api", builder.GetEdmModel(), new DefaultODataPathHandler(), conventions);

}

public class MyAttributeRoutingConvention : AttributeRoutingConvention
{
    public MyAttributeRoutingConvention(string routeName, HttpConfiguration configuration) : base(routeName, configuration)
    {
    }

    public override bool ShouldMapController(HttpControllerDescriptor controller)
    {
       if (controller.ControllerType == typeof(Module1EntitiesController))
       {
          return IsModule1Enabled;
       }
       if (controller.ControllerType == typeof(Module2EntitiesController))
       {
          return IsModule2Enabled;
       }
       return base.ShouldMapController(controller);
    }
 }


protected void Application_Start(object sender, EventArgs e)
{
    GlobalConfiguration.Configure(Register);
}

终于找到更简单的方法了。

此启动代码 ovveride OData $元数据路径和 return 禁止响应。

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.EnableDependencyInjection();
            endpoints.Select().Filter().OrderBy().Count().MaxTop(24);
            endpoints.MapODataRoute("ODataRoute", "odata", GetEdmModel());
            endpoints.MapGet("/odata/$metadata", async context =>
            {
                context.Response.StatusCode = 403;
                await context.Response.WriteAsync("Forbidden!");
            });
            endpoints.MapGet("/", context =>
            {
                context.Response.Redirect("/swagger");
                return Task.CompletedTask;
            });
        });