对象类型在.NET 6中显示为空数组。

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

object type is showing as an empty array in .net 6

问题

我正在从.NET Core 2.1迁移到.NET 6。我有一个返回类型为Task的端点,我有一个类,其中包含object类型的属性。经过一些检查后,我返回一个对象的Ok结果,即return Ok(myObj);。这在.NET Core 2.1中可以正常工作,但在.NET 6中,某种原因导致对象属性返回空数组。

我在.NET 6中创建了一个新应用程序,尝试复制问题,以查看是否在迁移时犯了错误,但似乎也不起作用。新项目如下:

[HttpGet("test")]
public IActionResult Test()
{
    var features = new Dictionary<string, bool>()
    {
        { "Foo", true },
        { "Bar", false }
    };
    var settings = new Dictionary<string, string>()
    {
        { "font-size", "16-px" },
        { "showOnStartUp", "no" }
    };
    var resp = new Result()
    {
        InnerDto = new InnerDto()
        {
            Foo = BuildObject(features.Select(f => new KeyValuePair<string, object>(f.Key, f.Value)).ToDictionary(k => k.Key, v => v.Value)),
            Bar = BuildObject(settings.Select(f => new KeyValuePair<string, object>(f.Key, f.Value)).ToDictionary(k => k.Key, v => v.Value))
        },
        S = "Test"
    };

    return Ok(resp);
}

private static object BuildObject(Dictionary<string, object> foo)
{
    var objects = foo.Select(f => new
    {
        Key = f.Key,
        Value = SetSettingsValueBasedOnType(f)
    }).ToList();

    var sb = new StringBuilder();
    sb.AppendLine("{");

    for (int i = 0; i < objects.Count; i++)
    {
        string val;
        var obj = objects[i];
        if (bool.TryParse(obj.Value.ToString(), out var parsedVal))
        {
            val = obj.Value.ToString().ToLower();
        }
        else
        {
            val = JsonConvert.SerializeObject(obj.Value);
        }

        var line = $@"""{obj.Key}"":{val}";
        sb.AppendLine(line);
        if (i < objects.Count - 1)
        {
            sb.Append(',');
        }
    }
    sb.AppendLine("}");
    var featuresObj = JsonConvert.DeserializeObject(sb.ToString());
    return featuresObj;
}

private static object SetSettingsValueBasedOnType(KeyValuePair<string, object> bar)
{
    object val;
    if (bool.TryParse(bar.Value.ToString(), out var parseVal))
    {
        val = parseVal;
    }
    else
    {
        val = bar.Value;
    }
    return val;
}

public class Result
{
    public string S { get; set; }
    public InnerDto InnerDto { get; set; }
}

public class InnerDto
{
    public object Foo { get; set; }
    public object Bar { get; set; }
}

逻辑在返回Ok之前的最后一行之前运行,如下所示:
对象类型在.NET 6中显示为空数组。

我收到的响应如下:
对象类型在.NET 6中显示为空数组。

是什么原因使它在.NET Core 2.1上工作而在.NET 6上不起作用?

英文:

I am migrating from .netcore 2.1 to .net 6. I have an endpoint that has a return type of Task<IActionResult> I have a class that has properties of type object.
And after some checks i am returning an ok result of my object i.e return Ok(myObj);
This is working without any problems in .netcore 2.1 but in .net6 the object properties are returning empty arrays for some reason.
I created a new app directly in .net 6 and tried to replicate the issue to see if it is some mistake in I did while migrating or not but it seems that it doesn't work either. The new project looks like this :

 [HttpGet(&quot;test&quot;)]   
public IActionResult Test()
{
var features = new Dictionary&lt;string, bool&gt;()
{
{ &quot;Foo&quot;, true },
{ &quot;Bar&quot;, false }
};
var settings = new Dictionary&lt;string, string&gt;()
{
{ &quot;font-size&quot;, &quot;16-px&quot; },
{ &quot;showOnStartUp&quot;, &quot;no&quot; }
};
var resp = new Result()
{
InnerDto = new InnerDto()
{
Foo = BuildObject(features.Select(f =&gt; new KeyValuePair&lt;string, object&gt;(f.Key, f.Value)).ToDictionary(k =&gt; k.Key, v =&gt; v.Value)),
Bar = BuildObject(settings.Select(f =&gt; new KeyValuePair&lt;string, object&gt;(f.Key, f.Value)).ToDictionary(k =&gt; k.Key, v =&gt; v.Value))
},
S = &quot;Test&quot;
};
return Ok(resp);
}
private static object BuildObject(Dictionary&lt;string, object&gt; foo)
{
var objects = foo.Select(f =&gt; new
{
Key = f.Key,
Value = SetSettingsValueBasedOnType(f)
}).ToList();
var sb = new StringBuilder();
sb.AppendLine(&quot;{&quot;);
for (int i = 0; i &lt; objects.Count; i++)
{
string val;
var obj = objects[i];
if (bool.TryParse(obj.Value.ToString(), out var parsedVal))
{
val = obj.Value.ToString()!.ToLower();
}
else
{
val = JsonConvert.SerializeObject(obj.Value);
}
var line = $@&quot;&quot;&quot;{obj.Key}&quot;&quot;:{val}&quot;;
sb.AppendLine(line);
if (i &lt; objects.Count - 1)
{
sb.Append(&#39;,&#39;);
}
}
sb.AppendLine(&quot;}&quot;);
var featuresObj = JsonConvert.DeserializeObject(sb.ToString());
return featuresObj!;
}
private static object SetSettingsValueBasedOnType(KeyValuePair&lt;string, object&gt; bar)
{
object val;
if (bool.TryParse(bar.Value.ToString(), out var parseVal))
{
val = parseVal;
}
else
{
val = bar.Value;
}
return val;
}
}
public class Result
{
public string S { get; set; }
public InnerDto InnerDto { get; set; }
}
public class InnerDto
{
public object Foo { get; set; }
public object Bar { get; set; }
}

the logic is working to last line before the return ok as you can see here:
对象类型在.NET 6中显示为空数组。
and the response I'm getting is like this:
对象类型在.NET 6中显示为空数组。

What is making this work on .netcore 2.1 and not on .net 6 ?

答案1

得分: 1

只需在使用Newtonsoft.JSON时,将对象序列化添加到您的对象中。

将这个代码块:

return Ok(resp);

更改为:

return Ok(JsonConvert.SerializeObject(resp, Formatting.Indented));

现在我们知道它有效,我们可以通过以下方式将其全局添加到所有控制器:

builder.Services.AddControllers()
    .AddNewtonsoftJson();

在这种情况下,您可能需要安装以下包:

<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.13" />

然后这也将起作用:return Ok(resp);

这是您的输出图:

对象类型在.NET 6中显示为空数组。

Microsoft文档链接:https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.newtonsoftjsonmvcbuilderextensions.addnewtonsoftjson?view=aspnetcore-6.0

英文:

if you are using Newtonsoft.JSON, it is fine, just add serialize object to your object.

Change this

return Ok(resp);

to

return Ok(JsonConvert.SerializeObject(resp, Formatting.Indented));

Now we know it works, we could add it globally to all controllers by doing this:

builder.Services.AddControllers()
.AddNewtonsoftJson();

In this case, you might need to install the following package:

&lt;PackageReference Include=&quot;Microsoft.AspNetCore.Mvc.NewtonsoftJson&quot; Version=&quot;6.0.13&quot; /&gt;

Then this will also work return Ok(resp);

And here is your output:

对象类型在.NET 6中显示为空数组。

Microsoft doc: https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.dependencyinjection.newtonsoftjsonmvcbuilderextensions.addnewtonsoftjson?view=aspnetcore-6.0

huangapple
  • 本文由 发表于 2023年2月14日 18:42:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75446678.html
匿名

发表评论

匿名网友

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

确定