1

I have created an attribute for action names. I want to get the attribute names in my service. I tried so many solutions but it doesn't return anything. This is my attribute class:

public class CustomeAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
}

This is the action that I used the attribute for:

   [Custome(Name ="ُShow courses")]
    public IActionResult Index()
    {
        var course = _courseService.GetAllCourses();
        return View(course);
    }

This is the method that I want to return the attribute name:

 public IList<ActionAndControllerName> AreaAndActionAndControllerNamesList(Assembly asm)
    {

        var contradistinction = asm.GetTypes()
            .Where(type => typeof(Controller).IsAssignableFrom(type))
            .SelectMany(type =>
                type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | 
       BindingFlags.Public))
            .Select(x => new
            {
                Controller = x.DeclaringType?.Name,
                //Action = x.Name,
                //Action=x.DeclaringType?.GetCustomAttributes(typeof(CustomeAttribute), false),
                // 
         
       Action=x.DeclaringType?.CustomAttributes.Where(c=>c.AttributeType==typeof(CustomeAttribute)),
                // Action=x.DeclaringType?.GetCustomAttributes(typeof(CustomeAttribute), false),
                // Action=x.DeclaringType?.CustomAttributes(typeof(CustomeAttribute), false),
                //Action=x.DeclaringType?.GetCustomAttribute(typeof(CustomeAttribute), false),
                Action=x.DeclaringType?.GetCustomAttributes<CustomeAttribute>(),
                //Action = x.DeclaringType?.GetCustomAttributes().Where(a => a.GetType() == 
          typeof(CustomeAttribute))
                Area = x.DeclaringType?.CustomAttributes.Where(c => c.AttributeType == 
           typeof(AreaAttribute)),
               
            });
        }

As I said I tried the solutions above that are commented but none of them worked. What should I do?

2
  • not sure what you mean by none of them worked, at least there should be some data returned although it may not be what you want (e.g: you want a string but the returned data is an IEnumerable<Attribute>). Try this Action = x.DeclaringType.GetCustomAttribute<CustomAttribute>()?.Name - That should work, note about the extension generic method GetCustomAttribute<T> which requires the namespace System.Reflection. Commented Mar 10, 2021 at 16:41
  • Thank you but it returns null. Commented Mar 12, 2021 at 4:51

2 Answers 2

1

You can try to save Name to some place in ActionfilterAttribute.Here is a demo to save data to session in OnActionExecuting method:

TestController:

        SomeOtherClass _someOtherClass;
        public TestController(SomeOtherClass someOtherClass)
        {
            _someOtherClass = someOtherClass;
        }
        [Custome(Name = "Show courses")]
        public IActionResult TestActionFilterAttribute()
        {
            var Name = _someOtherClass.TestGet();
            return Ok();
        }

SomeOtherClass:

public class SomeOtherClass
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private ISession _session => _httpContextAccessor.HttpContext.Session;

        public SomeOtherClass(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public string TestGet()
        {
            return _session.GetString("Custome_Name");
        }
    }

Startup.cs(IHttpContextAccessor can help get seesion outside controller):

public void ConfigureServices(IServiceCollection services)
        {
            ...
            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromDays(1);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddSingleton<SomeOtherClass, SomeOtherClass>();


        }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

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

        app.UseSession();

        ...
    }

CustomeAttribute:

public class CustomeAttribute: ActionFilterAttribute
    {
        public string Name { get; set; }
       

        public override void OnActionExecuting(ActionExecutingContext
                                           context)
        {
            if (Name != null) 
            {
                context.HttpContext.Session.SetString("Custome_Name", Name);
            }
      
        }


        public override void OnActionExecuted(ActionExecutedContext
                                              context)
        {
        }
    }

result: enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you but is there any way to get it in the method by GetCustomAttribute like those ways I tried or the CustomAttribute that I used to get areas?
0

I found the solution.I shouldn't have used "DeclaringType" in service. This is the solution:

var contradistinction = asm.GetTypes()
            .Where(type => typeof(Controller).IsAssignableFrom(type))
            .SelectMany(type =>
                type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | 
           BindingFlags.Public))
            .Select(x => new
            {
                Controller = x.DeclaringType?.Name,                  
                Action = x.GetCustomAttribute<CustomeAttribute>()?.Name,
                Area = x.DeclaringType?.CustomAttributes.Where(c => c.AttributeType == 
             typeof(AreaAttribute)),
            });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.