【问题标题】:Posting a dictionary to .net core 3.1. API将字典发布到 .net core 3.1。 API
【发布时间】:2020-06-18 11:56:59
【问题描述】:

我想将以下 DTO 发布到 .NET Core API:

{
    "Name": "Foo",
    "Street": "Bar",
    "DynamicInfo": {
        "MetadataAsString": "23423",
        "MetadataAsInt": 2,
        "MetadataAsBool": true,
        "SomeOtherValues": "blub"
    }
}

我想在 C# 中映射它的类如下所示:

public class Foo
{
    public string Name { get; set; }
    public string Street { get; set; }
    public Dictionary<string, object> DynamicInfo { get; set; }
}

您可以看到我使用了两个静态属性(名称和街道),但我还想发布一些动态数据。
我希望将动态数据写入字典,但不幸的是这不起作用。
我在调试器中得到的结果有点令人困惑:

所以值成功到达,但格式奇怪......我什至不知道如何访问这些值。
如何将其转换为仅包含对象的普通字典?

【问题讨论】:

  • DynamicInfo 列表是否受到某种限制?我的意思是你能不能有一个类 DynamicInfo,它会保存所有不同的可能值并基于类型的序列化?
  • 如果您在调试器中有数据(我会说这看起来确实像您的输入数据),那么您确实在字典中有数据。您是否尝试过myFoo.DynamicInfo["MetadataAsString"],是否得到了一个值为"23423" 的字符串对象?
  • 不...它绝对灵活。
  • @crashmstr:在这种情况下,我得到:“ValueKind = String:”23423“”。而且我仍然不确定这是什么......
  • 不只是在调试器中,而是在代码中访问它?另外,你告诉它是“对象”,所以要对它做任何事情,你需要检查它是什么类型,将它用作数字、布尔值或字符串。

标签: c# json .net-core


【解决方案1】:

对于不依赖于您的用例的解决方案,我将使用 2 个对象。 1 个用于客户端输入,1 个用于验证输入。客户端输入对象将包含Dictionary&lt;string,string&gt;。如果您仍然打算使用经过验证的输入,则可以包含您的 Dictionary&lt;string,object&gt;

如果你使用这种方法。在验证客户端输入期间,您可以使用bool.TryParse(DynamicInfo["MetadataAsBool"], out YourBoolean)。然后只需将YourBoolean 添加到您的新Dictionary&lt;string,object&gt; objectDictionary 中,例如objectDictionary.Add("BoolMetadata", YourBoolean)

【讨论】:

  • 但这迫使我的客户将所有 int 和 bool 值转换为字符串......但我也已经考虑过这个解决方案......
  • 好吧,本着最佳实践的精神,我看到了 2 个可供您选择的选项。要么使用强类型对象并让类型序列化完成工作,而不是使用代表数据请求的Dictionary&lt;string,object&gt;。或者使用TryParse 手动验证Dictionary&lt;string,string&gt; 对象中的字符串。
【解决方案2】:

我找到了解决方案。结果对象 (ValueKind=String: 23423) 只不过是一个 JSONElement。我以前不明白这一点。
这个 JSONElement 有一个枚举,它告诉我我有什么数据类型,所以我可以使用它来将我的 JSONElements 字典映射到另一个“真实”对象字典。

var newDic = new Dictionary<string, object>();
            foreach (var d in obj.DynamicInfo)
            {
                object obt;
                string key = d.Key;
                var a = enterprise.BasicInformation.TryGetValue(key, out obt);
                if (obt == null) continue;
                var doc = (JsonElement)obt;

                string myString = null;
                bool? myBool = null;
                int? myInteger = null;
                double? myFloatNumber = null;
                if (doc.ValueKind == JsonValueKind.String)
                {
                    myString = doc.ToString();
                }

                if (doc.ValueKind == JsonValueKind.True)
                {
                    myBool = true;
                }
                if (doc.ValueKind == JsonValueKind.False)
                {
                    myBool = false;
                }
                if (doc.ValueKind == JsonValueKind.Number)
                {
                    double floatNumber;
                    doc.TryGetDouble(out floatNumber);
                    if ((floatNumber % 1) == 0)
                    {
                        myInteger = (int)floatNumber;
                    }
                    else
                    {
                        myFloatNumber = floatNumber;
                    }
                }
                if (myString != null)
                {
                    newDic.Add(key, myString);
                }
                if (myBool != null)
                {
                    newDic.Add(key, myBool);
                }
                if (myInteger != null)
                {
                    newDic.Add(key, myInteger);
                }
                if (myFloatNumber != null)
                {
                    newDic.Add(key, myFloatNumber);
                }
            }

代码可能并不完美 - 我会尝试优化它。但它做了它应该做的。

【讨论】:

    猜你喜欢
    • 2020-03-31
    • 1970-01-01
    • 2021-07-18
    • 2020-12-04
    • 2022-01-18
    • 2020-11-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多