C# 使用System.Text.json.Serialization将动态对象转换为json时引发异常

C# 使用System.Text.json.Serialization将动态对象转换为json时引发异常,c#,.net-core,system.text.json,C#,.net Core,System.text.json,我想将动态对象转换为json字符串。当我在过去使用Newtonsoft.Json时,它工作得非常好。当我将.NETCore升级到3.0并改用System.Text.Json时,情况很糟糕 参见代码: using System; using System.Collections.Generic; using System.Dynamic; namespace ConsoleApp { class Program { static void Main(string[]

我想将动态对象转换为json字符串。当我在过去使用Newtonsoft.Json时,它工作得非常好。当我将.NETCore升级到3.0并改用System.Text.Json时,情况很糟糕

参见代码:

using System;
using System.Collections.Generic;
using System.Dynamic;
namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic product = new ExpandoObject();
            product.ProductName = "Elbow Grease";
            product.Enabled = true;
            product.Price = 4.90m;
            product.StockCount = 9000;
            product.StockValue = 44100;
            product.Tags = new string[] { "Real", "OnSale" };

            // Will output: { "ProductName":"Elbow Grease","Enabled":true,"Price":4.90,
            // "StockCount":9000,"StockValue":44100,"Tags":["Real","OnSale"]}
            var json1 = Newtonsoft.Json.JsonConvert.SerializeObject(product);
            Console.WriteLine(json1);

            // Both will throw exception: System.InvalidCastException:“Unable to
            // cast object of type '<GetExpandoEnumerator>d__51' to type
            // 'System.Collections.IDictionaryEnumerator'.”
            var json2 = System.Text.Json.JsonSerializer.Serialize(product);
            Console.WriteLine(json2);
            var json3 = System.Text.Json.JsonSerializer.Serialize<IDictionary<string, object>>(product as IDictionary<string, object>);
            Console.WriteLine(json3);

            Console.ReadKey();
        }
    }
}
使用系统;
使用System.Collections.Generic;
运用系统动力学;
名称空间控制台
{
班级计划
{
静态void Main(字符串[]参数)
{
动态产品=新的ExpandooObject();
product.ProductName=“弯头润滑脂”;
product.Enabled=true;
产品价格=4.90米;
product.StockCount=9000;
product.StockValue=44100;
Tags=新字符串[]{“Real”,“OnSale”};
//将输出:{“ProductName”:“弯头润滑脂”,“已启用”:true,“价格”:4.90,
//“StockCount”:9000,“StockValue”:44100,“Tags”:[“Real”,“OnSale”]}
var json1=Newtonsoft.Json.JsonConvert.SerializeObject(产品);
控制台写入线(json1);
//两者都将抛出异常:System.InvalidCastException:“无法
//将类型为“d__51”的对象强制转换为类型
//'System.Collections.IDictionaryEnumerator'
var json2=System.Text.Json.JsonSerializer.Serialize(产品);
控制台写入线(json2);
var json3=System.Text.Json.JsonSerializer.Serialize(产品作为IDictionary);
控制台写入线(json3);
Console.ReadKey();
}
}
}
如果我听说动态对象的转换比其他Json转换快,所以我想使用System.Text.Json来转换动态对象,那我该怎么办呢?

从2019年10月21日起,这将被记录为stil Open

您可以改用匿名类型

var product = new {
            ProductName = "Elbow Grease",
            Enabled = true,
            Price = 4.90m,
            StockCount = 9000,
            StockValue = 44100,
            Tags = new string[] { "Real", "OnSale" }
        };


var json1 = Newtonsoft.Json.JsonConvert.SerializeObject(product);
Console.WriteLine(json1);

var json2 = System.Text.Json.JsonSerializer.Serialize(product);
Console.WriteLine(json2);

谢谢你的提醒。我们决定重新使用Newtonsoft JSON,因为我们的项目通过Dapper动态对象结果使用了如此巨大的查询。该项目被用作从许多业务系统查询和组装数据的中心服务。由于数据对象之间的关系往往在很长的一段时间内是固定的,而数据对象的更改往往只是添加或删除一些字段,所以使用动态对象技术的方式,我们不需要修改任何代码,它仍然可以很好地运行。
ExpandoObject
的序列化在.NET 5中工作,请参见。expando被解释为一个
IDictionary
。要将自由格式的JSON反序列化为动态,您可以使用
ObjectAsPrimitiveConverter
from并设置
objectFormat=objectFormat.Expando
{"ProductName":"Elbow Grease","Enabled":true,"Price":4.90,"StockCount":9000,"StockValue":44100,"Tags":["Real","OnSale"]}
{"ProductName":"Elbow Grease","Enabled":true,"Price":4.90,"StockCount":9000,"StockValue":44100,"Tags":["Real","OnSale"]}