Getting fields of a class through reflection - reflection

I've done it a gazillion times in the past and successfully so. This time, I'm suffering from lapses of amnesia.
So, I am just trying to get the fields on an object. It is an embarrassingly simple and stupid piece of code that I am writing in a test solution before I do something really useful in production code.
Strangely, the GetFieldsOf method reports a zero length array on the "Amazing" class. Help.
class Amazing
{
private NameValueCollection _nvc;
protected NameValueCollection _myDict;
}
private static FieldInfo[] GetFieldsOf(string className,
string nameSpace = "SomeReflection")
{
Type t;
return (t = Assembly.GetExecutingAssembly().GetType(
string.Format("{0}.{1}", nameSpace, className)
)) == null ? null : t.GetFields();
}

Have a look at BindingFlags.
Try to set at least BindingFlags.Instance | BindingFlags.NonPublic in your GetFields() call.

Related

Finding unrecognized query params in ASP.NET Web API

I've got a fairly lengthy Get() method in an ASP.NET Web API controller. Something like this:
public PaginatedResult Get(int perPage = 10, int pageNum = 0, string param1 = null, [...] string param20 = null)
What I'd like is to be able to handle circumstances where a request includes a query param that's not part of the method signature. That is, if someone requests this:
/?perPage=10&paran19=foo&param21=bar
...I want to be able to say, "hey there, neither 'paran19' nor 'param21' exist, so they won't affect the results of this query!"
The only way I can think of to handle this is to call GetQueryNameValuePairs() on the Request, and then use reflection to compare that list with the params accepted by my Get() method. That seems like overkill for this problem though. Is there a better way? Ideally one flexible enough to be easily applied to several methods.
So, hopefully this self-answer isn't poor form on S.O., but with a little prodding from Cj S.'s answer, I looked more into the Web API message lifecycle, and ended up creating an Action Filter:
public class QueryParamMatchingActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext filterContext)
{
List<string> queryParamNames = filterContext.Request.GetQueryNameValuePairs().Select(q => (string)q.Key.ToLowerInvariant()).ToList();
List<string> methodParams = filterContext.ActionArguments.Select(q => (string)q.Key.ToLowerInvariant()).ToList();
List<string> unrecognized = queryParamNames.Where(qp => !methodParams.Any(mp => mp == qp)).ToList();
if (unrecognized.Count > 0)
{
List<string> errors;
if (filterContext.Request.Properties.ContainsKey("MY_ERRORS"))
errors = (List<string>)filterContext.Request.Properties["MY_ERRORS"];
else
errors = new List<string>();
foreach (string badParam in unrecognized)
{
errors.Add(String.Format("UNRECOGNIZED PARAMETER IGNORED: {0}", badParam));
}
filterContext.Request.Properties["MY_ERRORS"] = errors;
}
}
}
So now I can just decorate my controllers with "[QueryParamMatchingActionFilter]". The contents of MY_ERRORS get put into the response by a DelegatingHandler I already had setup, which wraps responses with some useful metadata. But this code should be easy enough to repurpose toward doing other things with extraneous params. The ability to use the ActionArguments property of filterContext means we get to skip using reflection, but I still wouldn't be surprised if someone else knew of a more efficient way to do this!

C# - Determine at runtime if property is a Type or an Object instance?

I want to determine whether MyBindingSource.DataSource is assigned to the designer set Type, or if it has been assigned an object instance. This is my current (rather ugly) solution:
Type sourceT = MyBindingSource.DataSource.GetType();
if( sourceT == null || sourceT.ToString().Equals("System.RuntimeType") ) {
return null;
}
return (ExpectedObjType) result;
The System.RuntimeType is private and non-accessible, so I can't do this:
Type sourceT = MyBindingSource.DataSource.GetType();
if ( object.ReferenceEquals(sourceT, typeof(System.RuntimeType)) ) {
return null;
}
return (ExpectedObjType) result;
I was just wondering if a better solution exists? Particularly one that doesn't rely on the Type name.
Since System.RuntimeType is derived from System.Type you should be able to do the following:
object result = MyBindingSource.DataSource;
if (typeof(Type).IsAssignableFrom(result.GetType()))
{
return null;
}
return (ExpectedObjType)result;
or even more concisely:
object result = MyBindingSource.DataSource;
if (result is Type)
{
return null;
}
return (ExpectedObjType)result;
Coincidentally this is the approach adopted here.
You don't have to ToString() it; you should be able to access its Name through GetType() (which is pretty much the same thing). Either way, because it's a private class and not accessible from developer code, I think you're stuck with a "magic string" if you need to verify that it is specifically a RuntimeType. Not all "best solutions" are as elegant as we'd like.
If all Type parameters you'd get are actually RuntimeType objects, you can look for the base class as was suggested in another answer. However, if you can receive a Type that isn't a RuntimeType, you'll get some "false positives".

How do I create a shallow copy of an object so that it may be serialize and sent via a web method call?

I would like to serialize the properties of the HttpBrowserCapibilities object so that it may be returned via a web method call. Currently the object cannot be serialized:
Cannot serialize member System.Web.Configuration.HttpCapabilitiesBase.Capabilities of type System.Collections.IDictionary, because it implements IDictionary.
...which is understandable. However, I would like to simply copy out the properties and their values to a hierarchy, i.e.
<HttpBrowserCapabilities>
<IsMobile>true</IsMobile>
</HttpBrowserCapabilities>
I'm starting to think I would need to use reflection to copy this object, but I haven't reached a conclusion. Does anyone have any suggestions to keep this simple?
Thanks,
George
Originally I posted an answer using XmlDocument, but I glossed over some of the web method stuff and didn't realize you were really trying to map a DTO.
Reflection sounds complicated but it really isn't. The following snippet will do what you want:
public static void Populate(object dest, IDictionary dictionary)
{
Type t = dest.GetType();
foreach (object key in dictionary)
{
PropertyInfo prop = t.GetProperty(key.ToString(),
BindingFlags.Instance | BindingFlags.Public);
if ((prop != null) && prop.CanWrite)
{
object value = dictionary[key];
prop.SetValue(dest, value, null);
}
}
}
Then invoke this as:
BrowserCapsDto dto = new BrowserCapsDto();
Populate(dto, Capabilities); // Capabilities is the real BrowserCaps
It's pretty easy because you already have an IDictionary and thus you already know all of the possible names you can map; you don't actually need to use any reflection on the source, just the destination.

strongly typed sessions in asp.net

Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions
http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx
http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx
http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx
and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics
public static class SessionManager<T> where T:class
{
public void SetSession(string key,object objToStore)
{
HttpContext.Current.Session[key] = objToStore;
}
public T GetSession(string key)
{
return HttpContext.Current.Session[key] as T;
}
}
Is there any inherent advantage in
using
SessionManager<ClassType>.GetSession("sessionString")
than using
HttpContext.Current.Session["sessionString"] as ClassType
I was also thinking it would be nice
to have something like
SessionManager["sessionString"] = objToStoreInSession,
but found that a static class cannot have an indexer. Is there any other way to achieve this ?
My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.
public class SessionObject { public Type type {get;set;} public Object obj{get;set;} }
this would not work as well (as the return signature would be the same, but the return types will be different).
Is there any other elegant way of saving/retrieving objects in session in a more type safe way
For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.
A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.
I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.
You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html
Actually, if you were looking to type objects, place the type at the method level like:
public T GetValue<T>(string sessionKey)
{
}
Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).
Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:
public class SessionManager
{
private static SessionManager _instance = null;
public static SessionManager Create()
{
if (_instance != null)
return _instance;
//Should use a lock when creating the instance
//create object for _instance
return _instance;
}
public object this[string key] { get { .. } }
}
And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.
I posted a solution on the StackOverflow question is it a good idea to create an enum for the key names of session values?
I think it is really slick and contains very little code to make it happen. It needs .NET 4.5 to be the slickest, but is still possible with older versions.
It allows:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
to work exactly like:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;

VB.NET Tracing Variables

I'm working on an approach to trace logging for my company's VB.NET project. The .NET framework has pretty versatile trace capabilities and I'd like to use what .NET already provides. My company wants to stay away from 3rd party software, so log4net and whatnot is out of the question.
They want to be able to trace the flow of the web application, and using trace sources, listeners, and switches will make this part pretty easy. However, they want me to trace when variables change throughout the program without having to write Trace.Write("i = " & i) every other line in a calculation.
So, any efficient approaches out there to do this?
Your answers are appreciated. Thanks in advance.
I decided to go with making a class. I simply made a TraceVariable Class that had an IntegerChanged event. This way, the developers of other parts of the code, will be able to control how to handle the variable change, if he wanted to do something other than trace it.
Here's the code:
Public Class TraceVariable
Private mInteger As Integer
Public Event IntegerChanged(ByVal mInteger As Integer)
Public Property TraceInteger() As Integer
Get
TraceInteger = mInteger
End Get
Set(ByVal value As Integer)
mInteger = value
RaiseEvent IntegerChanged(mInteger)
End Set
End Property
End Class
Thanks for the answers! As for the this being messy, we're only going to use it for critical variables, so no worries. Tracing in our situation is a necessity and a safety precaution.
Tracing every variable change would quickly become messy and lead to information overload for any but the most trivial of applications.
If there are specific variables that you want to trace the changes in, wrap them in a simple self-rolled Traceable class with accessors that write out to Trace when you do an update.
If you are talking about primitive variables like int, double etc then this will be tough but if you need to trace access to your custom classes then all you need to do is place a few trace statements in your property setters and methods which modify state (mutators).
Now as for the primitive types you my try using some kind of AOP tool (like postsharp) to patch the IL code (mutators) for these primitive types to emit trace messages same as you might do for a user defined class.
Tracing when variables change seems pretty extreme... it's probably going to be slow.
I'm not aware of anything built into the framework that does this. Essentially, it's closer to profiling or debugging than to tracing.
You may want to try the following (warning => C#):
class Program
{
static void Main(string[] args)
{
test(1, "one");
test(2, "two");
test(3, "three");
Console.ReadLine();
}
private static void test(int x, string y)
{
DisplayParameterNameAndValue(() => x);
DisplayParameterNameAndValue(() => y);
}
static void DisplayParameterNameAndValue(Expression<Func<object>> parameter)
{
var expressionBody = parameter.Body;
MemberExpression memberExpression;
if (expressionBody is UnaryExpression)
{
memberExpression = (MemberExpression)((UnaryExpression)expressionBody).Operand;
}
else if (expressionBody is MemberExpression)
{
memberExpression = (MemberExpression)expressionBody;
}
else
{
throw new ArgumentException("parameter");
}
string parameterName = memberExpression.Member.Name;
object parameterValue = parameter.Compile().Invoke();
Console.WriteLine("{0} => {1}", parameterName, parameterValue);
}
}
The equivalent code in VB would be:
Module Module1
Sub Main()
test(1, "one")
test(2, "two")
test(3, "three")
Console.ReadLine()
End Sub
Private Sub test(ByVal x As Integer, ByVal y As String)
DisplayParameterNameAndValue(Function() x)
DisplayParameterNameAndValue(Function() y)
End Sub
Private Sub DisplayParameterNameAndValue(ByVal parameter As Expression(Of Func(Of Object)))
Dim expressionBody = parameter.Body
Dim memberExpression As MemberExpression
If TypeOf expressionBody Is UnaryExpression Then
memberExpression = DirectCast(DirectCast(expressionBody, UnaryExpression).Operand, MemberExpression)
ElseIf TypeOf expressionBody Is MemberExpression Then
memberExpression = DirectCast(expressionBody, MemberExpression)
Else
Throw New ArgumentException("parameter")
End If
Dim parameterName As String = memberExpression.Member.Name
Dim parameterValue As Object = parameter.Compile().Invoke()
Console.WriteLine("{0} => {1}", parameterName, parameterValue)
End Sub
End Module
I have test it, but it does not give me the same results as with c#, bad vb!
Hope this helps.

Resources