从ASP.NET Core中的中间件中的类和方法属性获取值[英] get values from class and method attribute in middleware in asp.net core

本文是小编为大家收集整理的关于从ASP.NET Core中的中间件中的类和方法属性获取值的处理方法,想解了从ASP.NET Core中的中间件中的类和方法属性获取值的问题怎么解决?从ASP.NET Core中的中间件中的类和方法属性获取值问题的解决办法?从ASP.NET Core中的中间件中的类和方法属性获取值问题的解决方案?那么可以参考本文帮助大家快速定位并解决问题,译文如有不准确的地方,大家可以切到English参考源文内容。

问题描述

在加载页面之前,是否可以从中间件中的属性获取数据? 这意味着如果我将属性附加到控制器,我可以在中间件中访问数据吗?

我现在的空属性:

public sealed class Secure : Attribute
{
    public Secure()
    {

    }

    public Secure(params string[] roles)
    {

    }
}

推荐答案

我想您最好自定义 ActionFilterAttribute 在Action Concute之前获取数据:

public class SecureAttribute : ActionFilterAttribute
{
    private readonly UserManager<ApplicationUser> _userManager;
    public SecureAttribute(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        //get data from query string
        if (context.ActionArguments.TryGetValue("returnUrl", out object value))
        {
            //returnUrl is the query string key name
            var query = value.ToString();
        }
        //get data from form
        if (context.ActionArguments.TryGetValue("test", out object model))
        {
            var data = model;  
        }
        //get data from log in User
        var USER = context.HttpContext.User;
        if(USER.Identity.IsAuthenticated)
        {
            var user =  _userManager.FindByNameAsync(USER.Identity.Name).Result;
            var roles = _userManager.GetRolesAsync(user).Result;
        }
        base.OnActionExecuting(context);
    }
}

控制器:

[ServiceFilter(typeof(SecureAttribute))]
public async Task<IActionResult> Index(string returnUrl)
{...}

[HttpPost]
[ServiceFilter(typeof(SecureAttribute))]
public IActionResult Index(Test test)
{
    return View(test);
}

startup.cs:

services.AddScoped<SecureAttribute>();

如果您使用身份来扮演角色,请确保以下面的方式注册服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("YourConnectionString")));
   
    services.AddIdentity<IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddScoped<SecureAttribute>();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

结果:

其他推荐答案

我最终实现了一个ActionFilterAttribute.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class SecureAttribute : ActionFilterAttribute
{
    private readonly string[] _roles;

    public SecureAttribute()
    {
        _roles = new string[0];
    }

    public SecureAttribute(params string[] roles)
    {
        _roles = roles;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        ISecureRepo repo = (ISecureRepo)context.HttpContext.RequestServices.GetService(typeof(ISecureRepo));
        IUserProcessResult user = repo.GetCurrentUserAsync().Result;
        UnauthorizedObjectResult unauth = new UnauthorizedObjectResult($"{StatusCodes.Status401Unauthorized} Unauthorized");

        if (!user.Null())
        {
            bool access = true;

            foreach (string role in this.Roles) 
            { 
                if (user.User.Features.Where(ft => ft.Feature.Name == role).Count() == 0)
                {
                    access = false;
                }
            }

            if (!access)
            {
                context.Result = unauth;
            }
        }
        else
        {
            context.Result = unauth;
        }
    }

    public IEnumerable<string> Roles => _roles;
}

其他推荐答案

找到了一个很好的示例,说明了如何访问中间件中的属性.
资料来源: -in-asp-net核/

创建属性:

public class TelemetryAttribute : Attribute
{
    public TelemetryEvent Event { get; set; }
        
    public TelemetryAttribute(TelemetryEvent ev)
    {
        Event = ev;
    }
}
 
public enum TelemetryEvent { SignUp, SignIn}

使用属性:

[TelemetryAttribute(TelemetryEvent.SignUp)]
public async Task<IActionResult> SignUp([FromBody]SignUpViewModel vm)
{
    // ...
}

使用中间件中的属性参数:

public class TelemetryMiddleware
{
    private RequestDelegate _next;
 
    public TelemetryMiddleware(RequestDelegate next)
    {
        _next = next;
    }
 
    public async Task Invoke(HttpContext context)
    {
        await _next(context);
            
        var endpoint = context.Features.Get<IEndpointFeature>()?.Endpoint;
        var attribute = endpoint?.Metadata.GetMetadata<TelemetryAttribute>();
        if (attribute != null && attribute.Event == TelemetryEvent.SignUp)
        {
            // your code here
        }
    }
}

本文地址:https://www.itbaoku.cn/post/2306456.html

问题描述

is it possible to get data from an attribute in middleware before the page is loaded? Meaning if I attach an attribute to a controller, can I access the data in middleware?

My for now empty attribute:

public sealed class Secure : Attribute
{
    public Secure()
    {

    }

    public Secure(params string[] roles)
    {

    }
}

推荐答案

I think you'd better custom ActionFilterAttribute to get the data before action excutes:

public class SecureAttribute : ActionFilterAttribute
{
    private readonly UserManager<ApplicationUser> _userManager;
    public SecureAttribute(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        //get data from query string
        if (context.ActionArguments.TryGetValue("returnUrl", out object value))
        {
            //returnUrl is the query string key name
            var query = value.ToString();
        }
        //get data from form
        if (context.ActionArguments.TryGetValue("test", out object model))
        {
            var data = model;  
        }
        //get data from log in User
        var USER = context.HttpContext.User;
        if(USER.Identity.IsAuthenticated)
        {
            var user =  _userManager.FindByNameAsync(USER.Identity.Name).Result;
            var roles = _userManager.GetRolesAsync(user).Result;
        }
        base.OnActionExecuting(context);
    }
}

Controller:

[ServiceFilter(typeof(SecureAttribute))]
public async Task<IActionResult> Index(string returnUrl)
{...}

[HttpPost]
[ServiceFilter(typeof(SecureAttribute))]
public IActionResult Index(Test test)
{
    return View(test);
}

Startup.cs:

services.AddScoped<SecureAttribute>();

If you use Identity to get the role,be sure register service like below:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("YourConnectionString")));
   
    services.AddIdentity<IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddScoped<SecureAttribute>();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

Result: enter image description here

其他推荐答案

I ended up implementing an ActionFilterAttribute.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class SecureAttribute : ActionFilterAttribute
{
    private readonly string[] _roles;

    public SecureAttribute()
    {
        _roles = new string[0];
    }

    public SecureAttribute(params string[] roles)
    {
        _roles = roles;
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        ISecureRepo repo = (ISecureRepo)context.HttpContext.RequestServices.GetService(typeof(ISecureRepo));
        IUserProcessResult user = repo.GetCurrentUserAsync().Result;
        UnauthorizedObjectResult unauth = new UnauthorizedObjectResult($"{StatusCodes.Status401Unauthorized} Unauthorized");

        if (!user.Null())
        {
            bool access = true;

            foreach (string role in this.Roles) 
            { 
                if (user.User.Features.Where(ft => ft.Feature.Name == role).Count() == 0)
                {
                    access = false;
                }
            }

            if (!access)
            {
                context.Result = unauth;
            }
        }
        else
        {
            context.Result = unauth;
        }
    }

    public IEnumerable<string> Roles => _roles;
}

其他推荐答案

Found a nice example of how to access attributes in middleware.
Source: https://michaelscodingspot.com/attributes-and-middleware-in-asp-net-core/

Create attribute:

public class TelemetryAttribute : Attribute
{
    public TelemetryEvent Event { get; set; }
        
    public TelemetryAttribute(TelemetryEvent ev)
    {
        Event = ev;
    }
}
 
public enum TelemetryEvent { SignUp, SignIn}

Use the attribute:

[TelemetryAttribute(TelemetryEvent.SignUp)]
public async Task<IActionResult> SignUp([FromBody]SignUpViewModel vm)
{
    // ...
}

Use attribute params in middleware:

public class TelemetryMiddleware
{
    private RequestDelegate _next;
 
    public TelemetryMiddleware(RequestDelegate next)
    {
        _next = next;
    }
 
    public async Task Invoke(HttpContext context)
    {
        await _next(context);
            
        var endpoint = context.Features.Get<IEndpointFeature>()?.Endpoint;
        var attribute = endpoint?.Metadata.GetMetadata<TelemetryAttribute>();
        if (attribute != null && attribute.Event == TelemetryEvent.SignUp)
        {
            // your code here
        }
    }
}
查看更多