System.Text.Json 对匿名对象的序列化

huangapple go评论85阅读模式
英文:

System.Text.Json serialization against an anonymous object

问题

我正在开发一个ASP .Net Core 3.1应用程序,将部分代码从另一个使用2.2版本的应用程序迁移过来。到目前为止,我想要从NewtonSoft JSON序列化库切换到新的库System.Text.Json,但我遇到了一些问题。

考虑一个用于提供HTTP-GET服务的函数,返回类型如下:

[HttpGet("myservice")]
public async Task<ActionResult<object>> GetDataAsync( ...

然后,最后一部分可以描述如下:

var items = new List<IMyInterface>();
int totalCount = ...
int min = ...
int max = ...

return new ActionResult<object>(new
{
    totalCount,
    min,
    max,
    items
});

然而,它不起作用:items集合被序列化为其声明的类型(IMyInterface),而不是实际的类型。我在这里阅读到这是一种预期行为,尽管对我来说不太直观。

我的问题是:是否有一种方便而可靠的方式来利用新的序列化器,即使处理匿名对象也能够正常工作? 我希望能够避免每次都创建一个特定的对象来组合结果。

更新:

通过以下方式似乎可以工作,但看起来很丑陋:

return new ActionResult<object>(new
{
    totalCount,
    min,
    max,
    items = items.Cast<object>()
});
英文:

I'm working on an ASP .Net Core 3.1 application, porting part of the code from another using 2.2. So far, I'd like to switch from the NewtonSoft JSON serialization library to the new one, System.Text.Json, but I have some trouble.

Consider a function to serve a HTTP-GET service with this returning type:

    [HttpGet(&quot;myservice&quot;)]
    public async Task&lt;ActionResult&lt;object&gt;&gt; GetDataAsync( ...

Then, the final part could be depicted as follows:

        var items = new List&lt;IMyInterface&gt;();
        int totalCount = ...
        int min = ...
        int max = ...

        return new ActionResult&lt;object&gt;(new
        {
            totalCount,
            min,
            max,
            items
        });

However, it doesn't work: the items collection is serialized by its declared type (IMyInterface), instead of the actual type(s). I read here that this is an expected behavior, although not so intuitive to me.

My question is: is there any convenient yet reliable way to leverage the new serializer even dealing with anonymous objects? I would avoid to create a specific object every time I can compose the result inline.

UPDATE:

doing this it seems to work, but it looks really ugly:

        return new ActionResult&lt;object&gt;(new
        {
            totalCount,
            min,
            max,
            items = items.Cast&lt;object&gt;()
        });

答案1

得分: 1

如果您将项目创建为 List<object>,则无需更改或执行任何操作。这可能是一种更清晰的方式,而不是在创建对象时将它们强制转换为对象。

英文:

DotNetFiddler

If you want to serialize the objects, why not initialize them as objects? Is there a requirement to create it strong typed?

    public static void Test()
    {
        var items = new List&lt;object&gt;() { new Class1 { Foo = &quot;foo1&quot;, Bar1 = &quot;Bar1&quot; }, new Class2 { Foo = &quot;foo1&quot;, Bar2 = &quot;Bar2&quot; } };
        int totalCount = 1;
        int min = 2;
        int max = 3;


        var root = new
        {
            totalCount,
            min,
            max,
            items,
        };

        var json = JsonSerializer.Serialize&lt;object&gt;(root, new JsonSerializerOptions { WriteIndented = true, });

        Console.WriteLine(json);
    }

If you create the items as List&lt;object&gt;, you dont have to change or do anything. This might be a cleaner way instead of casting each of them to object at time of creating the object.

huangapple
  • 本文由 发表于 2020年1月4日 00:06:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581708.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定