【问题标题】:How to Deserialise JsonDocument To POCO Using System.Text.Json如何使用 System.Text.Json 将 JsonDocument 反序列化为 POCO
【发布时间】:2021-01-30 18:13:27
【问题描述】:

使用 HttpClient 我将一个 json 文档发布到我的控制器。

   public async Task<string> PostAsync<T>(string url, T doc)
   {
        var json = JsonConvert.SerializeObject(doc);
        var response = await mHttp.PostAsync(url, new StringContent(json));
   }

当我在这里检查控制器时:

public async Task&lt;ActionResult&gt; Post([FromBody] object doc,string fid)

对象文档的格式如下:

ValueKind = Object : "{"id": "101zsdfgfgh","fid": "test1",......}

如果类型未知,如何将其反序列化?

【问题讨论】:

标签: c# json system.text.json


【解决方案1】:

我想像这样从 JsonDocument 转换

dynamic obj=jsonDoc.ToObject();

所以我做了一个扩展方法。 属性最终是 JsonElements - 这对我来说很好,通常我需要做一个 ToString()。

这是我的代码(未经过彻底测试,请注意...)

using System.Dynamic;
using System.Text.Json;
using System.Collections.Generic;

namespace MyJsonExtensions
{
    public static class Extensions
    {
        public static object ToObject(this JsonDocument jsonDoc)
        {
            return Convert(jsonDoc.RootElement);
        }

        private static object Convert(JsonElement json)
        {

          if (json.ValueKind!=JsonValueKind.Array && json.ValueKind!=JsonValueKind.Object)
          {
            return json;
          }

          var serialized=JsonSerializer.Deserialize<ExpandoObject>(json.GetRawText());
          var output=new ExpandoObject();
          var outputDict=(IDictionary<string,object>)output;
          
          foreach (var prop in (IDictionary<string,object>)serialized)
          {
            var propValue=(JsonElement)prop.Value;

            switch (propValue.ValueKind)
            {
              case JsonValueKind.Array:
                var list=new List<object>();
                foreach (var item in propValue.EnumerateArray())
                {
                  list.Add(Convert(item));
                }
                outputDict[prop.Key]=list.ToArray();
                break;

              case JsonValueKind.Object:
                ExpandoObject val=new ExpandoObject();
                var node=(IDictionary<string,object>)val;
                foreach (var objElement in propValue.EnumerateObject())
                {
                  var v=Convert(objElement.Value);
                  node.Add(objElement.Name,v);
                }
                outputDict[prop.Key]=val;
                break;

              default:
                outputDict[prop.Key]=prop.Value;
                break;
            }            
          }

          return output;
        }

    }
}

【讨论】:

    【解决方案2】:

    我可能是错的,但如果你使用一个你坚持的参数

     System.Text.Json 
    

    所以我认为答案是不使用参数

    public async Task<ActionResult> Post([FromBody] object doc,string fid)
    

    改成

    public async Task<ActionResult> Post(string fid)
    

    然后像这样反序列化请求的内容。

       string obj = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
       var doc = JsonConvert.DeserializeObject<dynamic>(obj);
    

    然后就可以使用JsonConvert来反序列化了。看起来效果不错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-19
      • 1970-01-01
      • 2020-06-23
      • 2021-12-08
      • 1970-01-01
      • 2021-12-30
      • 2021-08-15
      • 1970-01-01
      相关资源
      最近更新 更多