Is there a way to compose an anonymous type object from JSON without knowing about the object's structure before-hand?
I have a JSON string and I'd like to use to compose an object. I don't k开发者_运维知识库now about the object structure or properties yet, so I cannot code a structure using an anonymous type. I'm stuck in .NET 3.5 on this project, so I don't have access to the new .Net 4.0 features yet. My goal is to use the converted object in a template engine similar to WebForms, Spark, or Razor to populate template items in a document with values from a model.
I have tried JavaScriptSerializer, which has a DeserializeObject method, but it outputs a key/value dictionary instead of an object that resembles the JSON object. Any other ideas?
If it helps, here's a unit test that expresses what I'm trying to do:
[TestClass]
public class when_deserializing_json_to_an_object : given_a_json_serializer_context
{
private object _expectedSerializedObject;
private string _jsonStringToDeserialize;
private object _result;
protected override void Context()
{
base.Context();
_expectedSerializedObject = new
{
Test = "123"
};
_jsonStringToDeserialize = "{\"Test\":\"123\"}";
}
protected override void BecauseOf()
{
_result = ObjectConverter.Deserialize(_jsonStringToDeserialize);
}
[TestMethod]
public void it_should_return_the_expected_object()
{
var modelType = _result.GetType();
var modelProperties = modelType.GetProperties();
var testProperty = modelProperties.SingleOrDefault(x => x.Name == "Test");
testProperty.GetValue( _result, null ).ShouldEqual( "123" );
}
}
public abstract class given_a_json_serializer_context : SpecificationBase
{
protected IObjectConverter ObjectConverter;
private JavaScriptSerializer _javascriptSerializer;
protected override void Context()
{
_javascriptSerializer = new JavaScriptSerializer();
ObjectConverter = new JsonObjectConverter(_javascriptSerializer) as IObjectConverter;
}
}
(SpecificationBase is a class that our team uses to help us with BDD style specifications in MSTest)
So far, the production code born out of the specification above is as follows:
public class JsonObjectConverter : IObjectConverter
{
private readonly JavaScriptSerializer _javascriptSerializer;
public JsonObjectConverter(JavaScriptSerializer javascriptSerializer)
{
_javascriptSerializer = javascriptSerializer;
}
public object Deserialize(string json)
{
return _javascriptSerializer.DeserializeObject(json);
}
}
At this point, it's clear that the JavaScriptSerializer isn't going to do the trick, because it just turns the JSON into a key/value pair dictionary.
You can't create an anonymous type like this but you can emit a new class.
Anonymous types are only anonymous to you. The compiler generates an actual type for all anonymous types and at run-time there is a real type associated with the anonymous types. Those types are not generated at run-time.
However, you can create a deserializer that uses Reflection.Emit
or any similar (more powerful) library to generate a new class at run-time that has the appropriate structure and then instantiate and populate that class.
You might find this of help Json.NET:
"Json.NET is a popular high-performance JSON framework for .NET"
http://json.codeplex.com/
精彩评论