Asp.net core mvc 将ApplicationModel的实例注入到MVC服务中,MVC服务本身就是一个单例
我希望仅当主体可以访问导航树的组件(无论是基于角色还是基于策略)时,才显示这些组件 我对MVC core不是特别熟悉,但阅读到目前为止的内容表明,我可以建立一个列表,列出将应用于某个操作的授权过滤器,如下所示:Asp.net core mvc 将ApplicationModel的实例注入到MVC服务中,MVC服务本身就是一个单例,asp.net-core-mvc,Asp.net Core Mvc,我希望仅当主体可以访问导航树的组件(无论是基于角色还是基于策略)时,才显示这些组件 我对MVC core不是特别熟悉,但阅读到目前为止的内容表明,我可以建立一个列表,列出将应用于某个操作的授权过滤器,如下所示: public NavigationNodePermissionResolver(ApplicationModel appModel) { foreach (var controllerModel in appModel.Controllers)
public NavigationNodePermissionResolver(ApplicationModel appModel)
{
foreach (var controllerModel in appModel.Controllers)
{
var contextFilters = controllerModel.Filters.OfType<IAsyncAuthorizationFilter>().ToList();
foreach (ActionModel action in controllerModel.Actions)//todo restrain to HttpGet
{
var actionFilters = action.Filters.OfType<IAsyncAuthorizationFilter>().ToList();
}
}
公共导航NodePermissionResolver(应用程序模型appModel)
{
foreach(appModel.Controllers中的var controllerModel)
{
var contextFilters=controllerModel.Filters.OfType().ToList();
foreach(controllerModel.Actions中的ActionModel action)//todo约束到HttpGet
{
var actionFilters=action.Filters.OfType().ToList();
}
}
如何将应用程序模型的实例注入NavigationNodePermissionResolver的实例化器
NavigationNodePermissionResolver本身将可注入为:
services.TryAddSingleton<INavigationNodePermissionResolver, NavigationNodePermissionResolver>();
services.TryAddSingleton();
编辑
这个问题的后续问题是:当我有一个IAsyncAuthorizationFilters列表时,该怎么办
作为后续信息,ApplicationModel是我在中了解到的ApplicationModelProviderContext的一个属性-它似乎与我所追求的大致相同,但可能是我用来获取并执行授权筛选器的方法完全错误我发现我可以实例化并注入相同的实例它实现了2个接口。我最终进入了Startup.ConfigureServices:
var customAppModelProvider = new CustomApplicationModelProvider();
services.AddSingleton<IApplicationModelProvider>(customAppModelProvider);
services.AddSingleton<IActionFilterMap>(customAppModelProvider);
var customAppModelProvider=new CustomApplicationModelProvider();
服务。AddSingleton(customAppModelProvider);
服务。AddSingleton(customAppModelProvider);
以及实施:
public interface IActionFilterMap
{
IEnumerable<IAsyncAuthorizationFilter> GetFilters(string area, string controller, string action);
}
public class CustomApplicationModelProvider : IApplicationModelProvider, IActionFilterMap
{
//It will be executed after AuthorizationApplicationModelProvider, which has order -990
public int Order => 0;
private ReadOnlyDictionary<ActionKey, IEnumerable<IAsyncAuthorizationFilter>> _authDictionary;
public IEnumerable<IAsyncAuthorizationFilter> GetFilters(string area, string controller, string action)
{
var key = new ActionKey(area, controller, action);
if (_authDictionary.TryGetValue(key, out IEnumerable<IAsyncAuthorizationFilter> returnVar))
{
return returnVar;
}
return null;//returning null rather than Enumerable.Empty so consuming method can detect if action found and has no Authorization, or action not found
}
public void OnProvidersExecuted(ApplicationModelProviderContext context)
{
var returnVar = new Dictionary<ActionKey, IEnumerable<IAsyncAuthorizationFilter>>();
foreach (var controllerModel in context.Result.Controllers)
{
var controllerFilters = controllerModel.Filters.OfType<IAsyncAuthorizationFilter>().ToList();
string area = controllerModel.Attributes.OfType<AreaAttribute>().FirstOrDefault()?.RouteValue;
foreach (ActionModel action in controllerModel.Actions)//todo restrain to get
{
var method = action.Attributes.OfType<HttpMethodAttribute>().FirstOrDefault();
if (method == null || method.HttpMethods.Contains("GET"))
{
var key = new ActionKey(area, controllerModel.ControllerName, action.ActionName);
if (action.Filters.OfType<AllowAnonymousFilter>().Any())
{
returnVar.Add(key, Enumerable.Empty<IAsyncAuthorizationFilter>());
}
else
{
var filters = controllerFilters.Concat(action.Filters.OfType<IAsyncAuthorizationFilter>()).ToArray();
returnVar.Add(key, filters);
}
}
}
_authDictionary = new ReadOnlyDictionary<ActionKey, IEnumerable<IAsyncAuthorizationFilter>>(returnVar);
}
}
public void OnProvidersExecuting(ApplicationModelProviderContext context)
{
//empty
}
private class ActionKey : Tuple<string, string, string>
{
public ActionKey(string area, string controller, string action) : base(area ?? string.Empty, controller, action)
{
_hashCode = base.GetHashCode();
}
int _hashCode;
public override int GetHashCode()
{
return _hashCode;
}
}
}
公共接口IActionFilterMap
{
IEnumerable GetFilters(字符串区域、字符串控制器、字符串操作);
}
公共类CustomApplicationModelProvider:IAApplicationModelProvider、IActionFilterMap
{
//它将在AuthorizationApplicationModelProvider(订单号为-990)之后执行
公共整数顺序=>0;
私人只读字典;
公共IEnumerable GetFilters(字符串区域、字符串控制器、字符串操作)
{
var键=新操作键(区域、控制器、操作);
if(_authDictionary.TryGetValue(key,out IEnumerable returnVar))
{
returnVar;
}
return null;//返回null而不是Enumerable.Empty,以便使用方法可以检测是否找到了操作并且没有授权,或者是否找不到操作
}
已执行公共void OnProvidersExecuted(ApplicationModelProviderContext上下文)
{
var returnVar=newdictionary();
foreach(context.Result.Controllers中的var controllerModel)
{
var controllerFilters=controllerModel.Filters.OfType().ToList();
字符串区域=controllerModel.Attributes.OfType().FirstOrDefault()?.RouteValue;
foreach(controllerModel.Actions中的ActionModel action)//todo约束获取
{
var method=action.Attributes.OfType().FirstOrDefault();
if(method==null | | method.HttpMethods.Contains(“GET”))
{
var key=新的ActionKey(区域,controllerModel.ControllerName,action.ActionName);
if(action.Filters.OfType().Any())
{
returnVar.Add(key,Enumerable.Empty());
}
其他的
{
var filters=controllerFilters.Concat(action.filters.OfType()).ToArray();
returnVar.Add(键、过滤器);
}
}
}
_authDictionary=新的只读字典(returnVar);
}
}
public void OnProvidersExecuting(ApplicationModelProviderContext上下文)
{
//空的
}
私有类ActionKey:Tuple
{
公共操作键(字符串区域、字符串控制器、字符串操作):基(区域??字符串。空、控制器、操作)
{
_hashCode=base.GetHashCode();
}
int_hashCode;
公共覆盖int GetHashCode()
{
返回hashCode;
}
}
}