Having problem getting private members using reflection.

K

Ken Varn

I have an ASP.NET application that is calling a custom class that is trying
to parse all of the members of my Page object using Type.GetMembers(). The
problem that I am having is that private members are not returned. I did
some digging and the MSDN documentation states that the caller must have
ReflectionPermission in order to get the private members of a class. I am a
little unfamiliar with this stipulation. I have checked the docs on
ReflectionPermission, but the examples do not make much sense. Could
someone please clarify on what I need to do in order for my code to be able
to parse private members of my Page using reflection?

--
-----------------------------------
Ken Varn
Senior Software Engineer
Diebold Inc.

EmailID = varnk
Domain = Diebold.com
-----------------------------------
 
B

Brock Allen

You need to use the overload that accepts a BindingFlags with this bitmask:

BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance

The simple version of GetMembers only returns the public ones (and maybe
internal and protected too. I can't remember exactly).

As for the ReflectionPermission, if you're running in FullTrust you have
the permission. This security check is so mobile downloaded code won't be
able to scrape thru all private members changing their values. That would
be a problem.
 
K

Ken Varn

I am using the BindingFlags that you indicated, and I still cannot get
private members.

--
-----------------------------------
Ken Varn
Senior Software Engineer
Diebold Inc.

EmailID = varnk
Domain = Diebold.com
-----------------------------------
 
B

Brock Allen

Private members from the concrete class or the base class? IIRC, there's
one last bit of detail where private base class members are inaccessible
via reflection on the derived type. You have to walk up to the Type.BaseType
to fetch privates. Perhaps this is the problem?
 
K

Ken Varn

Here is a short sample of the problem.


public class test : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Button Button2;

private string TestValue;

public string TestValue2;

private void Page_Load(object sender, System.EventArgs e)
{
ParseMambers(this);
}

// Web Page Initialize code omitted...

private int ParseMembers(object StateObj)
{
Type T = StateObj.GetType();
int Count = 0;
MemberInfo[] MemberArray;

BindingFlags BindFlags = BindingFlags.Instance |
BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic;

MemberArray = T.GetMembers(BindFlags);

foreach (MemberInfo M in MemberArray)
{
if (M.Name == "TestValue")
{
Count++;
}

if (M.Name == "TestValue2")
{
Count++;
}
}

}

// When we get here, Count will only be 1, it should be 2.
return Count;
}


Note, that if I change TestValue to public, then Count is 2 when calling
ParseMembers.

The wierd this is that this problem only seems to be localized to the main
web Page object. If I declare some other class with private fields, it
seems to work fine.

--
-----------------------------------
Ken Varn
Senior Software Engineer
Diebold Inc.

EmailID = varnk
Domain = Diebold.com
-----------------------------------
 
K

Ken Varn

I think I figured out what is going on, but not sure how to solve it.

I just discovered that an ASP.NET web page is not actually running as the
type that I declare for the page. It appears that ASP.NET wraps my page
class as a derived class. When I look at it in the debugger, my type shows
up as a base class, not as the root derived class. Thus, when I try to
iterate using the this object, I get the wrong type and thus cannot find the
private members.

There is some strange voodoo going on behind the scenes here.

Now the question is, how can I actually get the type of my class by passing
it into a function? Apparently passing 'this' will not work for an ASP.NET
page.


--
-----------------------------------
Ken Varn
Senior Software Engineer
Diebold Inc.

EmailID = varnk
Domain = Diebold.com
 
B

Brock Allen

Ah, yes, makes more sense now. Yeah, that's how ASP.NET does things -- the
ASPX is a class which inherits form the codebehind file. That's why it says
"Inherits" in the @Page directive in the ASPX ;)

Anyway, just use typeof(YourCodeBehindClass) instead.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top