I have a solution that is comprised of two projects, a Blazor server website and a Class Library. In the class library, I created a class to allow me to add custom attributes to functions in other classes in the library. This allows me to decorate a function with roles that can access the function. I then have a class that gets called to pull those tags and checks the database for consensus. This works fine, when the calling function is a regular function. But, if it is an async function, the stack frame I am looking at returns a value of "MoveNext" instead of the name of the method. Is there a way to get the method name of the calling method if that method is async? Here is my pseudo code:
Class to add custom attributes:
namespace DataAccessLibrary
{
[AttributeUsage(AttributeTargets.Method |AttributeTargets.ReturnValue)]
public class MELAdvanceRoles: Attribute
{
public string[] _Roles { get; set; }
public MELAdvanceRoles(string[] roles)
{
_Roles = roles;
}
}
}
Example function that uses custom attributes:
namespace DataAccessLibrary
{
public class ProgramData: IProgramData
{
private readonly ISqlDataAccess _db;
private readonly IUserRights _userRights;
public ProgramData(ISqlDataAccess db, IUserRights userRights)
{
_db = db;
_userRights = userRights;
}
[MELAdvanceRoles(new string[] { "MANAGER", "EMPLOYEE", "READ_ONLY" })]
public async Task<int> UpdateProgram(ProgramModel program)
{
if (_userRights.CanUserEditProgram(program.id))
//protected stuff
}
else
{
throw new Exception("403 Forbidden");
}
}
}
CanUserEditProgram Function in _userRights
public bool CanUserEditProgram(int program_id)
{
//get roles in the custom attribute
string[] allowed_roles = GetMethodRoles();
// use that list for database stuff
}
public string[] GetMethodRoles()
{
string[] roles = { };
StackTrace stackTrace = new StackTrace();
//it seems that functions that are async are not on the second frame
string methodName = stackTrace.GetFrame(2).GetMethod().Name;
//mehtodname returns 'MoveNext' if the calling method is async
MethodInfo mInfo = stackTrace.GetFrame(2).GetMethod().ReflectedType.GetMethod(methodName);
//which means mInfo returns null
bool isDef = Attribute.IsDefined(mInfo, typeof(MELAdvanceRoles));
if (isDef)
{
MELAdvanceRoles obsAttr = (MELAdvanceRoles)Attribute.GetCustomAttribute(mInfo, typeof(MELAdvanceRoles));
if (obsAttr != null)
{
roles = obsAttr._Roles;
}
}
return roles;
}
Thanks