0

How can I pass a generic method type parameter as a variable to it? Below given is the crud example of what I want to achieve. It's just for a demo purpose, not the actual code. I can use if...else or switch to go through passed category and call generic method with corresponding type parameter.

[HttpGet]
[Route("{category}")]
public IActionResult Get(string category)
{
    object data = new object();
    string json = GetData(category);
    if (category == "User")
    {
        data = JsonConvert.DeserializeObject<User>(json);
    }
    else if (category == "Organization")
    {
        data = JsonConvert.DeserializeObject<Organization>(json);
    }

    return Ok(data);
}

Assume GetData is a function which gives me a collection in a JSON format based on passed category. I want to call a generic method, DeserializeObject<T>(...), which requires a type parameter. The class which refers the type parameter is related to passed category. How to achieve like given below?

[HttpGet]
[Route("{category}")]
public IActionResult Get(string category)
{
    string json = GetData(category);
    T categoryType = GetCategoryType(category); // what should be here???
    object data = JsonConvert.DeserializeObject<categoryType>(json);

    return Ok(data);
}
6
  • 4
    "How can I pass a generic method type parameter as a variable to it?" - that isn't how generics are meant to be used. Generics enable static (i.e. compile-time) type information to be reified - for this scenario you should stick to good ol' fashioned vtable polymorphism. Commented Jul 14, 2021 at 13:53
  • 2
    A good counter-example to your notion is Get( category: DeleteEntireFileSystem ). You should never let external/remote clients have full control over deserialization: it leads to far too many vulnerabilities. Commented Jul 14, 2021 at 13:54
  • 3
    Does this answer your question? Setting generic type at runtime Commented Jul 14, 2021 at 13:55
  • "which gives me a collection in a JSON format based on passed category" - I'll bet you $50 USD that this is not what it does - simply because if you call GetData( "nextweekslotterynumbers" ) you won't get a JSON array of 7 numbers 0-49. You need to find out exactly what data GetData can return and then enforce that restriction in your controller action. This is part of defence in depth. Commented Jul 14, 2021 at 13:56
  • 1
    @Dai please don't focus on what GetData function is doing. It was taken just as an example. Commented Jul 14, 2021 at 14:12

1 Answer 1

1

JsonConvert.DeserializeObject does not require generics, it also accepts a Type object. Generics is not the right solution here.

Instead use this overload

JsonConvert.DeserializeObject(json, Type.GetType(yourNamespace + category))

I strongly suggest you maintain a whitelist of possible types if you are receiving the type name from user input.

Sign up to request clarification or add additional context in comments.

2 Comments

Here question is about any generic function not for Json.NET's DeserializeObject function. I mentioned it as an example just.
Then the duplicate is whta you want. If it was just an example of some generic code then you should have made that clear. I have answered the question that was asked

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.