在使用动态类型与System.Text.Json.Serialize时出现RuntimeBinder异常。

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

RuntimeBinder exception when using System.Text.Json.Serialize with dynamic type

问题

在上述代码中运行后,我得到了以下输出(只在 Release 模式下,而不在 Debug 模式下!)

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 调用在以下方法或属性之间模糊不清: 'System.Text.Json.JsonSerializer.Serialize<System.Text.Json.JsonSerializerOptions>(System.IO.Stream, System.Text.Json.JsonSerializerOptions, System.Text.Json.JsonSerializerOptions)' 和 'System.Text.Json.JsonSerializer.Serialize<System.Text.Json.JsonSerializerOptions&gt>(System.Text.Json.Utf8JsonWriter, System.Text.Json.JsonSerializerOptions, System.Text.Json.JsonSerializerOptions)' 在 CallSite.Target(Closure, CallSite, Type, Object, JsonSerializerOptions) 在 System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2) 在 Test.JsonUtil.PrettifyJson(String json) in D:\gitlab-runner\builds\RVQYCTWy\0\jpsc\developer\api-test\JsonUtil.cs:line 22

看起来存在一个问题,无法找到正确的 Serialize() 重载,因为第一个参数是 dynamic,但我不真的想在 PrettifyJson 上放置泛型类型,并且在 Debug 模式下它的工作正常。

有什么提示吗?

英文:
public string PrettifyJson(string json)
{
    dynamic? parsedJson = JsonSerializer.Deserialize&lt;dynamic&gt;(json);
    var optionPrettyPrint = new JsonSerializerOptions { WriteIndented = true };
    string formattedJson = JsonSerializer.Serialize(parsedJson, optionPrettyPrint);
    
    return formattedJson;
}

Running the above, I get (only in Release, not in Debug!)

> Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The call is ambiguous between the following methods or properties: 'System.Text.Json.JsonSerializer.Serialize<System.Text.Json.JsonSerializerOptions>(System.IO.Stream, System.Text.Json.JsonSerializerOptions, System.Text.Json.JsonSerializerOptions)' and 'System.Text.Json.JsonSerializer.Serialize<System.Text.Json.JsonSerializerOptions>(System.Text.Json.Utf8JsonWriter, System.Text.Json.JsonSerializerOptions, System.Text.Json.JsonSerializerOptions)' at CallSite.Target(Closure, CallSite, Type, Object, JsonSerializerOptions) at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2) at Test.JsonUtil.PrettifyJson(String json) in D:\gitlab-runner\builds\RVQYCTWy\0\jpsc\developer\api-test\JsonUtil.cs:line 22

It seems there is a problem to find the correct Serialize() overload, since the first parameter is dynamic, but I don't really want to have to put a generic type on PrettifyJson, and it works as expected in Debug mode.

Any hints?

答案1

得分: 1

我可以重现这个问题:只需将&quot;null&quot;作为json的值传入。此时,parsedJson是一个空引用,并且有多个可适用的重载。

修复方法只是避免使用动态类型,就我所见,这里实际上并没有给你带来任何好处 - 只需使用object代替:

public string PrettifyJson(string json)
{
    object? parsedJson = JsonSerializer.Deserialize<object>(json);
    var optionPrettyPrint = new JsonSerializerOptions { WriteIndented = true };
    string formattedJson = JsonSerializer.Serialize(parsedJson, optionPrettyPrint);
    
    return formattedJson;
}

然后,当解析“null”时,仍然会调用JsonSerializer.Serialize<object>(null, optionPrettyPrint),返回“null”。

英文:

I can reproduce the problem: just pass in &quot;null&quot; as the value for json. At that point, parsedJson is a null reference, and there are multiple overloads that are applicable.

The fix is to just avoid using dynamic typing, which isn't actually buying you anything here as far as I can see - just use object instead:

public string PrettifyJson(string json)
{
    object? parsedJson = JsonSerializer.Deserialize&lt;object&gt;(json);
    var optionPrettyPrint = new JsonSerializerOptions { WriteIndented = true };
    string formattedJson = JsonSerializer.Serialize(parsedJson, optionPrettyPrint);
    
    return formattedJson;
}

Then when "null" is parsed in, you still end up calling JsonSerializer.Serialize&lt;object&gt;(null, optionPrettyPrint) which returns "null" back.

huangapple
  • 本文由 发表于 2023年3月9日 15:47:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75681708.html
匿名

发表评论

匿名网友

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

确定