【问题标题】:How to read parse JSON String in C# [closed]如何在 C# 中读取解析 JSON 字符串 [关闭]
【发布时间】:2021-05-24 20:07:25
【问题描述】:

我正在尝试在 C# 中读取一个 JSON 字符串(实际上它要长得多,但只是为了显示结构......)这是我收到的字符串。

42["cti-agentes","{
    \"6139\":{
        \"id_agents_interface\":\"453\",
        \"agent\":\"6139\",
        \"interface\":\"contact1\",
        \"logintime\":\"2019-11-26 15:08:46\",
        \"pausetime\":\"2019-12-31 13:28:36\",
        \"paused\":\"si\",
        \"id_pausa\":null,
        \"invalid\":\"no\",
        \"invalidtime\":null,
        \"fullcontact\":\"contact1\",
        \"textoterminal\":\"contact1\"
        },
    \"6197\":{
        \"id_agents_interface\":\"5743\",
        \"agent\":\"6197\",
        \"interface\":\"contact1\",
        \"logintime\":\"2020-01-16 10:16:17\",
        \"pausetime\":null,
        \"paused\":\"no\",
        \"id_pausa\":null,
        \"invalid\":\"no\",
        \"invalidtime\":null,
        \"fullcontact\":\"contact2\",
        \"textoterminal\":\"contact2\"
        }
}"]

字符串应该是一个“代理”数组。 6139 是一个代理,具有所有属性,而 6197 是另一个代理。在这个例子中只有两个代理,但在真实的字符串中有很多。

我对 JSON 格式不是很熟悉,但我试图在这个 web https://jsonformatter.curiousconcept.com/ 中验证它,但我无法让它工作,所以也许我必须在解析它之前稍微“清理”一下字符串?希望你能帮忙。

应用程序应该能够读取 JSON 字符串并将其解析为 .NET 对象,我尝试了 JsonConvert.DeserializeObject()JArray.Parse() 函数,但它们都不适合我。

有什么帮助吗?

【问题讨论】:

  • 开头的“42”不应该在那里。此外,您还需要在将双引号放入验证器之前删除分隔双引号的反斜杠(我假设您是从调试视图中复制的,其中 VS 显示带有双引号分隔的字符串)
  • 这看起来像是一个转义字符串,可能是从调试器中获取的?请提供实际字符串。例如。在 Visual Studio 中使用选项 Text Visualizer
  • @AsierAzkolain 开头的 42 肯定会使这个 json 无效,所以你可能想要修剪它。你确定这是你收到的 100% 的字符串吗?如果您查看了 Visual Studio 调试器中的字符串,它可能是附加反斜杠的调试器。但是这个 json 存在多个问题......例如 cti-agents 的值被 "" 包围,这实际上使它成为一个字符串而不是一个 json 对象。
  • 如果这确实是您收到的内容,那么它是一个严重损坏的 JSON 响应,应该在 SERVER 端进行修复。您应该努力不接受它作为有效数据(因为它不是)并让另一方修复它。如果需要,请升级。
  • @AsierAzkolain 最好的办法是打电话给制造这种垃圾的“开发人员”,然后对他大喊大叫,直到他修复它。如果 42 只是为了模因,我不会感到惊讶 ;-)

标签: c# arrays json


【解决方案1】:

第一部分似乎是一个 int,你有多种方法可以删除它:

var withoutNumberPrefix = new string(input.SkipWhile(c=> Char.IsDigit(c)).ToArray());
var fixedSize = input.Substring(2, input.Length - 2);
var always42 = input.TrimStart(new[] { '4', '2' });

完成此操作后,您将拥有一个 List<string>,其中第一个值是类型,第二个值是该类型的“数组”。

var listResults = JsonConvert.DeserializeObject<string[]>(fixedSize);

你可以反序列化第二部分:

var result = JsonConvert.DeserializeObject<Dictionary<int,CtiAgentes>>(listResults[1]);

进入匹配类型,使用那些工具简单复制过去创建
How to auto-generate a C# class file from a JSON string

public partial class CtiAgentes
{
    [JsonProperty("id_agents_interface")]
    public int IdAgentsInterface { get; set; }

    [JsonProperty("agent")]
    public int Agent { get; set; }

    [JsonProperty("interface")]
    public string Interface { get; set; }

    [JsonProperty("logintime")]
    public DateTimeOffset Logintime { get; set; }

    [JsonProperty("pausetime")]
    public DateTimeOffset? Pausetime { get; set; }

    [JsonProperty("paused")]
    public string Paused { get; set; }

    [JsonProperty("id_pausa")]
    public object IdPausa { get; set; }

    [JsonProperty("invalid")]
    public string Invalid { get; set; }

    [JsonProperty("invalidtime")]
    public object Invalidtime { get; set; }

    [JsonProperty("fullcontact")]
    public string Fullcontact { get; set; }

    [JsonProperty("textoterminal")]
    public string Textoterminal { get; set; }
}

在这个Live demo 中,您会注意到除了“删除 42”之外没有任何字符串操作。不是反斜杠不是引号被修改。这是一个 json 硬编码在字符串 Store Hardcoded JSON string to variable

注意事项: 我将DateTimeOffset 用于PausetimeLogintime,因为该输入中没有时区。您可以使用 Datetime,但最好知道它是 gmt 还是本地化数据。

对于我选择的所有空值对象。因为我不知道类型。数据迟早会蓬勃发展。可以假设 id 是 int 且无效时间是 DateTimeOffSet,但我无法做出这样的决定。

【讨论】:

  • 嘿,谢谢!我正在对我的代码进行尝试,但 input.SkipWhile 似乎无法编译,这是为什么呢?前 3 行只删除了“42”,对吧?
  • 是的,3 种处理方式。 SkipWhile 是 linq,你错过了 using System.Linq;这对我来说是最好的解决方案,因为它也可以处理 123456789 和 0。如果大小改变或不是 42,其他两个将失败。使用 TrimStart 和所有数字是第二好的。
  • 然后点击现场演示并观看它运行。它会回答你的大部分问题
  • 很好,它有效,非常感谢!有点头疼;)
  • @AsierAzkolain,那是 5 行代码和 1 个副本过去。我在答案中添加了一个注释。阅读。因为我只假设基于不完整数据的类型,如null。这可能会随着真实数据而蓬勃发展。
【解决方案2】:

您的文字存在多个问题。我将尝试在以下部分中详细说明它们......

42 附加到字符串

对我们所有人来说都很明显 - 这不应该在那里

你的 json 对象是一个列表

由于您的 json 对象以 [ 开头,它实际上是一个字符串列表,必须用 , 分隔,例如["a", "b", "c"],这大概就是下一点的原因了……

您的 json 值对象是字符串

首先下面是字符串列表和json对象的混合体

"cti-agentes","{
\"6139\":{
    \"id_agents_interface\":\"453\",
    \"agent\":\"6139\",
    \"interface\":\"contact1\",
    \"logintime\":\"2019-11-26 15:08:46\",
    \"pausetime\":\"2019-12-31 13:28:36\",
    \"paused\":\"si\",
    \"id_pausa\":null,
    \"invalid\":\"no\",
    \"invalidtime\":null,
    \"fullcontact\":\"contact1\",
    \"textoterminal\":\"contact1\"
    },

但如果你想拥有 json 对象,你可能没有在你的对象周围环绕 "。 符号,因为它使它成为字符串而不是 json 对象,例如

"employee_1": { "name": "dominik" } 而不是

"employee_1": "{ "name": "dominik" }" 就像在您的示例中一样。

结论

为您提供“json”的系统不提供 json,而是提供一些类似于 json 的字符串。为什么?我不知道 - 可能是“42”哈哈 :)

最好的建议可能是与制作 api 的人交谈并修复它

我现在能做什么?

也许您可以尝试提取cti-agentes 的值,因为以下实际上是您应该能够解析的有效 json。

{
\"6139\":{
    \"id_agents_interface\":\"453\",
    \"agent\":\"6139\",
    \"interface\":\"contact1\",
    \"logintime\":\"2019-11-26 15:08:46\",
    \"pausetime\":\"2019-12-31 13:28:36\",
    \"paused\":\"si\",
    \"id_pausa\":null,
    \"invalid\":\"no\",
    \"invalidtime\":null,
    \"fullcontact\":\"contact1\",
    \"textoterminal\":\"contact1\"
    },
\"6197\":{
    \"id_agents_interface\":\"5743\",
    \"agent\":\"6197\",
    \"interface\":\"contact1\",
    \"logintime\":\"2020-01-16 10:16:17\",
    \"pausetime\":null,
    \"paused\":\"no\",
    \"id_pausa\":null,
    \"invalid\":\"no\",
    \"invalidtime\":null,
    \"fullcontact\":\"contact2\",
    \"textoterminal\":\"contact2\"
    }
}

【讨论】:

  • 感谢您的回答!我已经使用@DragandDrop 的答案解决了这个问题,但你的答案也很有帮助;)
猜你喜欢
  • 2014-01-06
  • 2014-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
相关资源
最近更新 更多