0

Ok a brief background. I'm trying out various ways to test an API and I'm trying to allow a user to provide a simple CSV file of a API calls that my test framework can iterate over using a generic test method. I'm having trouble passing the type to my generic API call method. Allow me to demonstrate.

Given I have a method with the following basic structure

public T GetData<T>(Uri uri, HttpStatusCode expectedStatusCode)
{
        var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
        myHttpWebRequest.Accept = "application/json";
        var response = (HttpWebResponse)myHttpWebRequest.GetResponse();

        if (response.StatusCode != expectedStatusCode)
            Report.Log(ReportLevel.Failure, "ExpectedResponseCode:" + expectedStatusCode.ToString() + " ActualResponseCode:" + response.StatusCode.ToString());

        string responseString = "";

        using (var stream = response.GetResponseStream())
        {
            var reader = new StreamReader(stream, Encoding.UTF8);
            responseString = reader.ReadToEnd();
        }

        return JsonConvert.DeserializeObject<T>(responseString);
    }

I can call the above as follows without issue

Person person = _apiHelper.GetData<Person>(uri, HttpStatusCode.Ok);

However assume I now have a Type that I have acquired as follows

Type returnType = Type.GetType(typeString, true, true);

why can I not call the GetData method as follows

var result = _apiHelper.GetData<returnType>(uri, HttpStatusCode.Ok);

Visual studio simply says it cant resolve the symbol

1 Answers1

5

Just use the JsonConvert.DeserializeType overload that accepts a type parameter instead of the generic one:

public object GetData(Type t,Uri uri, HttpStatusCode expectedStatusCode)
{
    ....
    return JsonConvert.DeserializeObject(responseString,t);
}

This is a case of the XY problem. You want to deserialize arbitrary types (problem X) and think that somehow, you need pass a generic type at runtime (problem Y), so when you get stuck ,you ask about Y.

Community
  • 1
  • 1
Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • Brilliantly finding the question behind the question. :) – Filipe Borges Sep 30 '16 at 12:49
  • @LasseV.Karlsen oops, got carried away. Passing the type was the original problem after all – Panagiotis Kanavos Sep 30 '16 at 12:52
  • @FilipeBorges a huge number of SO questions are actually XY. Too many customer requirements are XY as well. This question was well formatted and the code clean enough that finding X wasn't hard – Panagiotis Kanavos Sep 30 '16 at 12:54
  • I see; and then I can use reflection to to validate the individual properties of the returned object (which have also been passed in by my user as a KVP) – robert tonnessen Sep 30 '16 at 12:55
  • You shouldn't need to use reflection at all. Json.NET will return an instance of the target type as an Object. Just cast the object to the target type when you actually need to use it. – Panagiotis Kanavos Sep 30 '16 at 12:58
  • @PanagiotisKanavos I think I need to use reflection because my user has provided the following csv line route,responseCode,returnType,validationParams. validation params are a string of piped property names and values such as Surname|Smith*Gender|Male*Age|32 and so on. once I've made the generic web call above I will have an object that I want to pass to a generic validate method along with the kvp list. I then intend to loop over the list and check that the property has the value. – robert tonnessen Sep 30 '16 at 13:05