1

In my VS LIGHTSWITCH 2013 portal application I allow the user to create tiles that link to other internal apps. When a new tile is create a Role with the name 'TileTitle + " User"' is created. This way I can show and hide tiles based on a users roles. However when trying to filter the tile entities in the query filter method I get some error about not being able to use the IsInRole method.

After some digging I decided to give expression trees a try, and this is what I came up with:

partial void TileLinks_Filter(ref Expression<Func<TileLink, bool>> filter)
{
    ParameterExpression p = Expression.Parameter(typeof(TileLink), "e");
    MemberExpression ti = Expression.Property(p, "Title");
    MethodInfo m2 = typeof(string).GetMethod("Concat", new[] { typeof(string), typeof(string) });


    Type t = this.Application.User.GetType();
    MethodInfo m = t.GetMethod("IsInRole");

    Expression filterExpression = Expression.IsTrue(Expression.Call(Expression.Call(m2, ti, Expression.Constant(" User")), m));

    filter = Expression.Lambda<Func<TileLink, bool>>(filterExpression, p); 

    // e => this.Application.User.IsInRole(e.Title + " User"); 
    // this is what I would like to do
 }

This however does not work, and I am left with this very odd error message.

Method 'Boolean IsInRole(System.String)' declared on type 'System.Security.Claims.ClaimsPrincipal' cannot be called with instance of type 'System.String'

Please help me filter my data based on dynamically generated roles!

Felipe Miosso
  • 7,309
  • 6
  • 44
  • 55
cmaduro
  • 1,672
  • 3
  • 21
  • 40

1 Answers1

0

You've got your arguments reversed in the outer call to Expression.Call. If you broke your code out a bit, you'd end up with this:

var titlePlusUser = Expression.Call(m2, ti, Expression.Constant(" User"));
var isInRole = Expression.Call(titlePlusUser, m); // <<-- !!!
Expression filterExpression = Expression.IsTrue(isInRole);

This is instructing it to use e.Title + "User" as the object instance to call IsInRole on.

Instead you need to produce another expression that knows how to get this.Application.User, and pass that expression in as the first parameter.

var isInRole = Expression.Call(applicationUser, m, titlePlusUser);
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315