有条件地禁用 ASP.NET MVC 控制器

问题描述 投票:0回答:4

有条件禁用 ASP.NET MVC 控制器的最佳方法是什么?

如果 web.config 中的某个值是“true”,我想访问控制器操作;如果是“false”,则访问 404

我应该写自己的属性吗?

更新: 寻找比操作过滤器属性更优雅的解决方案(能够将非常量参数传递给属性构造函数)

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class CloseForSomeSettingAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            bool mySettingValue = MySettingManager.GetMySettingValue();

            if (mySettingValue)
            {
                filterContext.Result = new HttpStatusCodeResult(404);
            }
            else
            {
                base.OnActionExecuting(filterContext);
            }
        }
    }
c# asp.net .net asp.net-mvc asp.net-mvc-3
4个回答
6
投票

最简单的可能是实现自定义操作过滤器:

http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs

您还可以有条件地添加与该控制器匹配的路由,这将导致返回 404。


3
投票

在这里回答 - 防止 ASP.NET Core 在单独的程序集中发现控制器

这种方法不需要过滤器,并且对 swagger 等隐藏控制器。


0
投票

交叉发布:https://stackoverflow.com/a/43044667/257470

我禁用

ApiController
控制器的解决方案:

  • 使用 WebConfig AppSettings 配置标志而不是 (
    #if DEBUG
    )
  • 在调用方法之前
    ExecuteAsync
    拦截调用并检查功能切换(功能标志);
  • 如果功能被禁用,则返回
    HTTP 410 GONE
  • 如果对于许多控制器来说很常见,请将代码移至控制器的基类

代码:

public class TestController : ApiController
{
    public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
    {
        var featureFlag = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["EnableTest"]);

        if (featureFlag == false)
        {
            return Task.FromResult(new HttpResponseMessage(HttpStatusCode.Gone));
        }

        return base.ExecuteAsync(controllerContext, cancellationToken);
    }

0
投票

移除整个控制器组件可能不是一个可行的解决方案。相反,我们可以使用约定

创建一个约定

public class ControllerDisableConvention : IControllerModelConvention
{
    private readonly Type _controllerType;
    private readonly bool _inherit;
    public ControllerDisableConvention(Type controllerType, bool inherit = true)
    {
        _controllerType = controllerType;
        _inherit = inherit;
    }

    public void Apply(ControllerModel controller)
    {
        if ((!_inherit || !_controllerType.IsAssignableFrom(controller.ControllerType)) && _controllerType != controller.ControllerType)
        {
            return;
        }

        controller.ApiExplorer.IsVisible = false;
        controller.Actions.Clear();
        controller.Selectors.Clear();
        controller.ControllerProperties.Clear();
        controller.Filters.Clear();
        controller.Properties.Clear();
    }
}

用法

public virtual void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddControllers().AddMvcOptions(opts =>
   {
       opts.Conventions.AddControllerDisableConvention<LauncherController>();
   });
   ...
}

我还分享了一个nuget包

dotnet add package Ogu.AspNetCore.Conventions
© www.soinside.com 2019 - 2024. All rights reserved.