【问题标题】:Is there a way to compose an anonymous type object from JSON without knowing about the object's structure before-hand?有没有办法在事先不知道对象结构的情况下从 JSON 组合匿名类型对象?
【发布时间】:2011-01-06 20:23:14
【问题描述】:

我有一个 JSON 字符串,我想用它来组合一个对象。我还不知道对象结构或属性,所以我不能使用匿名类型对结构进行编码。我在这个项目中被困在 .NET 3.5 中,所以我还无法访问新的 .Net 4.0 功能。我的目标是在类似于 WebForms、Spark 或 Razor 的模板引擎中使用转换后的对象,用来自模型的值填充文档中的模板项。

我尝试过 JavaScriptSerializer,它有一个 DeserializeObject 方法,但它输出的是键/值字典,而不是类似于 JSON 对象的对象。还有其他想法吗?

如果有帮助,这里有一个单元测试来表达我正在尝试做的事情:

    [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 是我们团队用来帮助我们在 MSTest 中处理 BDD 样式规范的类)

到目前为止,从上面的规范中诞生的生产代码如下:

public class JsonObjectConverter : IObjectConverter
{
    private readonly JavaScriptSerializer _javascriptSerializer;

    public JsonObjectConverter(JavaScriptSerializer javascriptSerializer)
    {
        _javascriptSerializer = javascriptSerializer;
    }

    public object Deserialize(string json)
    {
        return _javascriptSerializer.DeserializeObject(json);
    }
}

在这一点上,很明显 JavaScriptSerializer 无法解决问题,因为它只是将 JSON 转换为键/值对字典。

【问题讨论】:

  • 我不确定我是否理解这是如何工作的。您的模板引擎是否使用反射来访问反序列化对象的字段?这是您正在编写的模板引擎还是其他?
  • 是的,模板引擎使用反射来查找所有属性。然后它会迭代属性并将相应的模板项替换为属性的值。

标签: c# json .net-3.5


【解决方案1】:

您不能像这样创建匿名类型,但可以发出一个新类。

匿名类型只对你是匿名的。编译器为所有匿名类型生成一个实际类型,并且在运行时有一个与匿名类型相关联的真实类型。这些类型不是在运行时生成的。

但是,您可以创建一个使用Reflection.Emit 或任何类似(更强大)库的反序列化程序,在运行时生成一个具有适当结构的新类,然后实例化并填充该类。

【讨论】:

    【解决方案2】:

    你可能会在 Json.NET 中找到这个帮助:

    “Json.NET 是 .NET 的流行的高性能 JSON 框架”

    http://json.codeplex.com/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多