tags:

views:

62

answers:

2

I have a WCF service that accepts an object as a parameter that has a URI and Method Name. What I am trying to do is have a method that will look @ the URI, if it contains the words "localhost" it will use reflection and call a method, of the name that is passed in as a parameter, within the the same class, return a value and continue on.

public class Test
{
     public GetStatResponse GetStat(GetStatRequest request)
     {

        GetStatResponse returnValue = new GetStatResponse();

         if(Helpers.Contains(request.ServiceURI,"localhost", StringComparison.OrdinalIgnoreCase))
         {
             MethodInfo mi = this.GetType().GetMethod(request.ServiceMethod /*, BindingFlags.Public | BindingFlags.IgnoreCase*/);
             returnValue = (GetStatResponse)mi.Invoke(this,null);
         }

The above is the code segment pertaining to this question. I pull the MethodInfo no problem but I am running into issues on the mi.Invoke. The exception that I receive is "Exception has been thrown by the target of an invocation." With an Inner Exception "Object reference not set to an instance of an object". I have tried changing the code to (GetStatResponse)mi.Invoke(new Test(), null), with no luck. Test being the class.

I'm open to other suggestions as to how to resolve this, I just thought reflection might be the easiest.

The Method that I am calling with my testing is defined as

public GetStatResponse TestMethod() 
{
         GetStatResponse returnValue = new GetStatResponse(); 
         Stat stat = new Stat();
         Stat.Label = "This is my label";
         Stat.ToolTip = "This is my tooltip";
         Stat.Value = "this is my value"; 

         returnValue.Stat = stat;
         return returnValue;
}
A: 

Before calling the method you might want to make sure that the MethodInfo you are pulling through reflection is not null:

MethodInfo mi = this.GetType().GetMethod(
    request.ServiceMethod, 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase
);

// Make sure that the method exists before trying to call it
if (mi != null)
{
    returnValue = (GetStatResponse)mi.Invoke(this, null);
}

After your update it seems that the exception is thrown inside the method you are calling:

GetStatResponse returnValue = new GetStatResponse(); 
// Don't forget to initialize returnValue.Stat before using it:
returnValue.Stat = new WhateverTheTypeIs();
returnValue.Stat.Label = "This is my label";
Darin Dimitrov
Thanks, good tip. In my testing I am specifying the method and the MethodInfo is being retrieved properly.
Matt
Locate the exact line where this exception is thrown. Could it be inside the method itself?
Darin Dimitrov
The exact line the exception is thrown is the returnValue = (GetStatResponse)mi.Invoke(this, null) The Method I am calling is now defined in my original post.
Matt
In the method you are calling I don't see where you are initializing the `returnValue.Stat` property. You write `returnValue.Stat.Label` which blows because `returnValue.Stat` is null.
Darin Dimitrov
Good catch. Resolved. Still same error.
Matt
Please debug your code step by step and see where exactly the exception is thrown. Which line?
Darin Dimitrov
The after I fixed that Stat issue you picked up on. The MethodInfo Object for whatever reason stopped populating with the MethodInfo. After I removed the BindingFlags from the GetMethod call everything started to work. Odd, the Method I"m calling is public but it didn't like the BindingFlags.Public option
Matt
Quick followup as well. The proper bindings are BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.InstanceThanks again!
Matt
Yes, those are the correct bindings. I've mentioned them in my answer.
Darin Dimitrov
A: 

Because you are not specifying BindingFlags in your GetMethod() call, you are only going to be returned methods matching the name containing request.ServiceMethod that are PUBLIC.

Check whether the method you are trying to invoke is public, otherwise MethodInfo will return null.

If it is not public, either make the method public or include the BindingFlags.NonPublic flag.

Also, you should always make sure that mi != null before calling mi.Invoke

Sam
The Method I am calling is Public. I have the BindingFlags in there, I just commented them out. Uncommenting them still yields the same result.
Matt