【问题标题】:Dynamic add property to a class based on Json output基于 Json 输出的类动态添加属性
【发布时间】:2019-03-22 02:37:15
【问题描述】:

我有一个JSON 字符串,其中记录可以更改。我在我的 JSON 字符串中的每个级别都使用public partial classes。我将它复制到DataTable,因为我在我的 SQL-Server 中需要它。我这样调用 JSON:

StringReader sr = new StringReader(json);
Newtonsoft.Json.JsonTextReader readera = new JsonTextReader(sr);
object result = (Welcome)jsona.Deserialize(readera,typeof(Welcome));

Welcome w = (Welcome)result;

DataTable da = w.Result.Records.ToDataTable(); 

例如,我的JSON 可以包含:

ID、名称、值

但其他JSON 可能包含:

身份证、地址、城市、邮政编码

我的班级现在看起来像这样:

public partial class Record
{
    [JsonProperty("Col1")]
    public DateTimeOffset Col1 { get; set; }

    [JsonProperty("Col2")]
    public long Col2 { get; set; }

    [JsonProperty("Col3")]
    public DateTimeOffset Col3 { get; set; }

    [JsonProperty("Col4")]
    public long Col4 { get; set; }

    [JsonProperty("Col5")]
    public string Col5 { get; set; }

如何使这个动态化?我真的不知道。

【问题讨论】:

    标签: c# json sql-server class dynamic


    【解决方案1】:

    您可以使用dynamic 数据类型代替类。这里的例子使用Json.net

    JObject obj = JsonConvert.DeserializeObject("{ 'Name': 'Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 28 }");
    
    var properties = obj.Properties();
    foreach (var prop in properties)
    {
        string key = prop.Name;
        object value = prop.Address;
        int age = prop.Age;         
    }
    

    【讨论】:

    • 但这要求我知道json字符串输出?
    • 您可以反序列化任何 json,但是要访问它们,您应该知道字符串输出。
    • 好的,谢谢。但我需要这样做,因为我什么都不知道。
    • 谢谢 - 你能纠正你的答案吗?你给我的最后一个链接帮助了我! :)
    【解决方案2】:

    您可以通过string 创建一个类并在运行时编译和加载它并通过反射设置值。

    在这个例子中,我将新类减少到只有一个属性。

    public Type BuildType(string propertyName)
        {
            var code = @"
                using System;
                namespace MyNamespace
                {
                    public class MyClass
                    {
                        public object " + propertyName + @" { get; set; }
                    }
                }";
    
            var provider = new CSharpCodeProvider();
            var parameters = new CompilerParameters
            {
                GenerateInMemory = true,
                GenerateExecutable = false
            };
    
            var results = provider.CompileAssemblyFromSource(parameters, code);
    
            // Check Errors
            if (results.Errors.HasErrors)
            {
                var sb = new StringBuilder();
                foreach (CompilerError error in results.Errors) 
                {
                    sb.AppendLine(string.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
                }
                throw new InvalidOperationException(sb.ToString());
            }
            var assembly = results.CompiledAssembly;
            var classInstance = assembly.GetType("MyNamespace.MyClass");
    
            return classInstance;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-13
      • 2017-10-16
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多