Casting object to Anonymous Types in C#

Posted by

Recently I was attempting to create an integration test where I called an API controller’s GET method directly from code, which returns an IActionResult. In this specific instance, I was returning an ObjectResult where the object itself was an anonymous type containing multiple different models.

var result = new { Status = status, Data = domainModel };
return StatusCode(status.Code, result);

In my test, I wanted to validate the data on one of the models in that anonymous type that is set in IActionResult’s value property. The problem is that IActionResult.Value is of type object, and its “definition” is in the controller as an anonymous object. So, I needed a way to cast that IActionResult.Value to that anonymous type so I can easily check the properties on the returned data. Unfortunately, this is easier said than done.

My first approach was to cast it to a JSON string. This would mean that I could then theoretically traverse the JSON object to get my specific data. However, I still just wanted to hit the object directly. As a result, I found the DeserializeAnonymousType method in Json.NET. Since it takes a JSON string as its input, I had to first serialize the object to its JSON string representation. It makes sense in theory, but I was still surprised that it does work:

string resultBody = JsonConvert.SerializeObject(result.Value);
var definition = new { Status = new StatusModel(), Data = new User() };
var anonymousResult = JsonConvert.DeserializeAnonymousType(resultBody, definition);

This anonymousResult variable does act like a normal anonymous type, and I can successfully access the child objects in it (ie, anonymousResult.Data.FirstName). Despite this technically working, it’s pretty goofy to serialize an object as json and back to an object, so I kept looking for a better solution, when I came across this StackOverflow post, which contains the following helper method:

private static T CastTo<T>(object value, T targetType)
{
    // targetType above is just for compiler magic
    // to infer the type to cast value to
    return (T)value;
}

This implicit type casting does work and makes the casting pretty easy, and under the covers, it appears that the JsonConvert methods appear to be doing similar things. Regardless, I have created a GitHub repository with a .NET Core Console App containing three methods (the JsonConvert method, the CastTo method, and an extension method version of the CastTo method) with examples, found here: https://github.com/mvalenta/ObjectToAnonymousExamples.

After all this work, I ended up opting for creating an ApiResult class to standardize the API responses. This makes doing my test cases way easier by just doing an implicit cast to ApiResult (IE, “var apiResult = (ApiResult)result.Value;”). Obviously, this is the best solution for my use case, as it doesn’t literally involve “compiler magic” or JSON shenanigans, but it’s nice to know that it is possible to convert an object to a defined anonymous type.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.