Asp.net core mvc 将ApplicationModel的实例注入到MVC服务中,MVC服务本身就是一个单例

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)

我希望仅当主体可以访问导航树的组件(无论是基于角色还是基于策略)时,才显示这些组件

我对MVC core不是特别熟悉,但阅读到目前为止的内容表明,我可以建立一个列表,列出将应用于某个操作的授权过滤器,如下所示:

    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;
}
}
}