有条件禁用 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);
}
}
}
最简单的可能是实现自定义操作过滤器:
您还可以有条件地添加与该控制器匹配的路由,这将导致返回 404。
在这里回答 - 防止 ASP.NET Core 在单独的程序集中发现控制器
这种方法不需要过滤器,并且对 swagger 等隐藏控制器。
交叉发布:https://stackoverflow.com/a/43044667/257470
我禁用
ApiController
控制器的解决方案:
#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);
}
移除整个控制器组件可能不是一个可行的解决方案。相反,我们可以使用约定
创建一个约定:
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