反序列化 JSON 并分配给模型
Deserialize JSON and assign to model
作为我的网络 api 的一部分,我得到以下 JSON 返回。
["{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}"]
我想要做的是获取 Filename
旁边的值并将其分配给我的模型 Filename
参数。
在我的项目中,我创建了一个单元测试来尝试获取该值,但我所做的每次尝试都失败了。
在我的测试中,我有以下 DTO 模型:
public class HangfireTestDTO
{
public string InputType { get; set; }
public string Filename { get; set; }
}
那么我的文字逻辑是这样的:
[Fact]
public void TestDTO()
{
string data =
"[\"{\\"InputType\\":12,\\"EngineSubType\\":2,\\"Filename\\":\\"targetFile.csv\\",\\"FileExtensionType\\":\\".csv\\",\\"IsLoadFile\\":true,\\"LoadContextId\\":4120,\\"ReportingDate\\":\\"2019-05-31T00:00:00\\",\\"IsSuccess\\":false}\"]";
// fails here
var arguments = System.Text.Json.JsonSerializer.Deserialize<HangfireTestDTO>(data);
// This is wrong - ignore for now
Assert.Equal("targetFile.csv", arguments.ToString());
}
当我在测试中调试上面的内容时,它告诉我以下内容:
The JSON value could not be converted to MyProject.HangfireTestDTO
然后我的想法让我再次尝试将反序列化行修改为以下内容:
var arguments = System.Text.Json.JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data).FirstOrDefault();
但是当 运行 换行时,我得到以下错误:
The JSON value could not be converted to System.Collections.Generic.List
我做错了什么?
第一个错误是因为 InputType
。应该是int
public class HangfireTestDTO
{
public int InputType { get; set; }
public string Filename { get; set; }
}
第二个错误是因为JSON
。 [
和{
之间有一个加引号。我已经尝试使用以下 JSON
并且它有效。由于这个引用,它变成 List<string>
而不是 List<HangfireTestDTO>
[
{
"InputType": 12,
"EngineSubType": 2,
"Filename": "targetFile.csv",
"FileExtensionType": ".csv",
"IsLoadFile": true,
"LoadContextId": 4120,
"ReportingDate": "2019-05-31T00:00:00",
"IsSuccess": false
}
]
并且查看 JSON
应该是 IEnumerable<HangfireTestDTO>
var arguments = JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data);
首先你的JSON是错误的
我希望它看起来更像
string data = @"[{""InputType"":12,""EngineSubType"":2,""Filename"":""targetFile.csv"",""FileExtensionType"":"".csv"",""IsLoadFile"":true,""LoadContextId"":4120,""ReportingDate"":""2019-05-31T00:00:00"",""IsSuccess"":false}]"
或
string data = "[{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}]"
其次,您将 JSON 包装在 [] 中,这意味着文档列表,因此 Deserialize<HangfireTestDTO>(data);
将是 Deserialize<List<HangfireTestDTO>>(data);
或其他一些 IEnumerable
然后你有几个数据不匹配 12 是一个数字而不是字符串所以 InputType 应该是一个 int 或 double,IsSuccess 是一个 bool,等等
最后,您的 JSON 中有很多字段不在您的对象中,您需要向 c# 解释如何处理它们,要么创建额外的属性,要么提供一个可以放置它们的 KeyValue 存储在
即
[JsonExtensionData]
public Dictionary<string, object> ExtensionData { get; set; }
如果数据真的是这样从你的数据库中出来的,那么在你发表的评论之后进行编辑,然后它是一个字符串数组,其中的字符串是 JSON 编码的
在这种情况下,您将需要读取字符串然后在
之后解析它们
var jsonlist = JsonSerializer.Deserialize<List<string>>(data);
foreach(string json in jsonlist )
var dto = JsonSerializer.Deserialize<HangfireTestDTO>(json);
您当前的 JSON 字符串是一个字符串数组。您需要首先将 JSON 反序列化为 字符串列表,然后将这些字符串中的每一个反序列化为 DTO。这是使用 JSON:
的完整示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
public class HangfireTestDTO
{
public int InputType { get; set; }
public int EngineSubType { get; set; }
public string Filename { get; set; }
public string FileExtensionType { get; set; }
}
class Program
{
static void Main()
{
string data =
"[\"{\\"InputType\\":12,\\"EngineSubType\\":2,\\"Filename\\":\\"targetFile.csv\\",\\"FileExtensionType\\":\\".csv\\",\\"IsLoadFile\\":true,\\"LoadContextId\\":4120,\\"ReportingDate\\":\\"2019-05-31T00:00:00\\",\\"IsSuccess\\":false}\"]";
// First deserialize the single string to a list of strings
List<string> jsonStrings = JsonSerializer.Deserialize<List<string>>(data);
// Then deserialize each of the strings to a DTO.
List<HangfireTestDTO> dtos = jsonStrings
.Select(json => JsonSerializer.Deserialize<HangfireTestDTO>(json))
.ToList();
Console.WriteLine(dtos.Count);
Console.WriteLine(dtos[0].Filename);
}
}
作为我的网络 api 的一部分,我得到以下 JSON 返回。
["{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}"]
我想要做的是获取 Filename
旁边的值并将其分配给我的模型 Filename
参数。
在我的项目中,我创建了一个单元测试来尝试获取该值,但我所做的每次尝试都失败了。
在我的测试中,我有以下 DTO 模型:
public class HangfireTestDTO
{
public string InputType { get; set; }
public string Filename { get; set; }
}
那么我的文字逻辑是这样的:
[Fact]
public void TestDTO()
{
string data =
"[\"{\\"InputType\\":12,\\"EngineSubType\\":2,\\"Filename\\":\\"targetFile.csv\\",\\"FileExtensionType\\":\\".csv\\",\\"IsLoadFile\\":true,\\"LoadContextId\\":4120,\\"ReportingDate\\":\\"2019-05-31T00:00:00\\",\\"IsSuccess\\":false}\"]";
// fails here
var arguments = System.Text.Json.JsonSerializer.Deserialize<HangfireTestDTO>(data);
// This is wrong - ignore for now
Assert.Equal("targetFile.csv", arguments.ToString());
}
当我在测试中调试上面的内容时,它告诉我以下内容:
The JSON value could not be converted to MyProject.HangfireTestDTO
然后我的想法让我再次尝试将反序列化行修改为以下内容:
var arguments = System.Text.Json.JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data).FirstOrDefault();
但是当 运行 换行时,我得到以下错误:
The JSON value could not be converted to System.Collections.Generic.List
我做错了什么?
第一个错误是因为 InputType
。应该是int
public class HangfireTestDTO
{
public int InputType { get; set; }
public string Filename { get; set; }
}
第二个错误是因为JSON
。 [
和{
之间有一个加引号。我已经尝试使用以下 JSON
并且它有效。由于这个引用,它变成 List<string>
而不是 List<HangfireTestDTO>
[
{
"InputType": 12,
"EngineSubType": 2,
"Filename": "targetFile.csv",
"FileExtensionType": ".csv",
"IsLoadFile": true,
"LoadContextId": 4120,
"ReportingDate": "2019-05-31T00:00:00",
"IsSuccess": false
}
]
并且查看 JSON
应该是 IEnumerable<HangfireTestDTO>
var arguments = JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data);
首先你的JSON是错误的 我希望它看起来更像
string data = @"[{""InputType"":12,""EngineSubType"":2,""Filename"":""targetFile.csv"",""FileExtensionType"":"".csv"",""IsLoadFile"":true,""LoadContextId"":4120,""ReportingDate"":""2019-05-31T00:00:00"",""IsSuccess"":false}]"
或
string data = "[{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}]"
其次,您将 JSON 包装在 [] 中,这意味着文档列表,因此 Deserialize<HangfireTestDTO>(data);
将是 Deserialize<List<HangfireTestDTO>>(data);
或其他一些 IEnumerable
然后你有几个数据不匹配 12 是一个数字而不是字符串所以 InputType 应该是一个 int 或 double,IsSuccess 是一个 bool,等等
最后,您的 JSON 中有很多字段不在您的对象中,您需要向 c# 解释如何处理它们,要么创建额外的属性,要么提供一个可以放置它们的 KeyValue 存储在 即
[JsonExtensionData]
public Dictionary<string, object> ExtensionData { get; set; }
如果数据真的是这样从你的数据库中出来的,那么在你发表的评论之后进行编辑,然后它是一个字符串数组,其中的字符串是 JSON 编码的
在这种情况下,您将需要读取字符串然后在
之后解析它们var jsonlist = JsonSerializer.Deserialize<List<string>>(data);
foreach(string json in jsonlist )
var dto = JsonSerializer.Deserialize<HangfireTestDTO>(json);
您当前的 JSON 字符串是一个字符串数组。您需要首先将 JSON 反序列化为 字符串列表,然后将这些字符串中的每一个反序列化为 DTO。这是使用 JSON:
的完整示例using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
public class HangfireTestDTO
{
public int InputType { get; set; }
public int EngineSubType { get; set; }
public string Filename { get; set; }
public string FileExtensionType { get; set; }
}
class Program
{
static void Main()
{
string data =
"[\"{\\"InputType\\":12,\\"EngineSubType\\":2,\\"Filename\\":\\"targetFile.csv\\",\\"FileExtensionType\\":\\".csv\\",\\"IsLoadFile\\":true,\\"LoadContextId\\":4120,\\"ReportingDate\\":\\"2019-05-31T00:00:00\\",\\"IsSuccess\\":false}\"]";
// First deserialize the single string to a list of strings
List<string> jsonStrings = JsonSerializer.Deserialize<List<string>>(data);
// Then deserialize each of the strings to a DTO.
List<HangfireTestDTO> dtos = jsonStrings
.Select(json => JsonSerializer.Deserialize<HangfireTestDTO>(json))
.ToList();
Console.WriteLine(dtos.Count);
Console.WriteLine(dtos[0].Filename);
}
}