如何将JSON反序列化为正确类型的对象,而不必事先定义类型?

kde*_*eez 10 c# serialization json deserialization

我搜索了类似的问题,找不到任何与我想要的相匹配的东西.

C#的新手请耐心等待.

我有一些json文件,我正在反序列化.我希望文件反序列化为正确类型的对象,而不必事先定义类型.这是我的代码:

public class loadJson
    {
        //path of the file location
        public void readJson(string path)
        {
            //array of files at the path location. right now just reading one file
            FileInfo[] files = new DirectoryInfo(path).GetFiles("seleniumExample.json").ToArray();

            foreach (FileInfo fi in files)
            {

                dynamic b1 = null;
                using (StreamReader file = new StreamReader(fi.FullName))
                {

                    string fileText = file.ReadToEnd();
                    //Console.WriteLine(fileText);

                    try
                    {
                        b1 = Newtonsoft.Json.JsonConvert.DeserializeObject(fileText);
                    }
                    catch(Exception e)
                    {
                        Console.WriteLine("ERROR!!!! " + e.ToString());
                    }

                    file.Close();
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我有一堆对象类型,我将通过json文件提供给我的程序.

我不想明确地将b1称为Bid,客户或任何其他特定的预定义类.如果我明确地将b1称为Bid,它会加载所有信息,并填写正确的实例变量.

但是当我使用"动态"或一般的"对象"时,它无法解决它并只是初始化为"对象".

有没有办法执行泛型反序列化并让它根据json文件中定义的字段创建正确类的对象?

在此先感谢您的帮助,如果我的问题非常不清楚,我会道歉.如果是这样,请让我知道如何帮助消除任何歧义.再次感谢.

dbc*_*dbc 15

通过使用该设置,Json.NET能够在序列化期间记录.Net对象类型的多态类型TypeNameHandling = TypeNameHandling.Auto.启用该设置后,.Net类型的多态对象将显示为名为的合成属性"$type",例如:

"$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests"
Run Code Online (Sandbox Code Playgroud)

但是,如果调用常规方法或者,"$type"则永远不会为对象发出该属性.相反,您必须使用一种接受"预期"根类型的序列化方法,例如或.传递为预期类型保证将显示type属性:JsonConvert.SerializeObject(Object)JsonSerializer.Serialize(TextWriter, Object)SerializeObject(Object, Type, JsonSerializerSettings)JsonSerializer.Serialize(TextWriter, Object, Type)typeof(object)

var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
var json = JsonConvert.SerializeObject(rootObject, typeof(object), settings);
Run Code Online (Sandbox Code Playgroud)

如果使用此设置创建JSON文件,JSON本身将记住序列化对象的类型.在反序列化期间,Json.NET将使用此类型,只要您将set设置TypeNameHandling为除了之外的其他类型TypeNameHandling.None.例如:

var settings = new Newtonsoft.Json.JsonSerializerSettings { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto };
b1 = Newtonsoft.Json.JsonConvert.DeserializeObject(fileText, settings);
Run Code Online (Sandbox Code Playgroud)

工作样本.Net 在这里小提琴.

注意事项:这种在JSON中存储.Net类型的方式是非标准的.其他序列化程序,例如DataContractJsonSerializer不处理此格式的类型信息.

请注意Newtonsoft文档中的这一注意事项:

当您的应用程序从外部源反序列化JSON时,应谨慎使用TypeNameHandling.使用非None以外的值进行反序列化时,应使用自定义SerializationBinder验证传入类型.

有关为什么需要这样做的讨论,请参阅Newtonsoft Json中的TypeNameHandling警告,如何配置Json.NET以创建易受攻击的Web API,以及AlvaroMuñoz和Oleksandr Mirosh的黑帽文章https://www.blackhat.com/docs/ us-17 /周四/ us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf.