Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化JSON并分配给模型_C#_Json_Deserialization_Json Deserialization - Fatal编程技术网

C# 反序列化JSON并分配给模型

C# 反序列化JSON并分配给模型,c#,json,deserialization,json-deserialization,C#,Json,Deserialization,Json Deserialization,作为web api的一部分,我将返回以下JSON ["{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}"] 我想做的是获取Filena

作为web api的一部分,我将返回以下JSON

["{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}"]
我想做的是获取
Filename
旁边的值,并将其分配给我的models
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());

}
[事实]
公共void TestDTO()
{
字符串数据=
“[\“{\\\\\”输入类型\\\\”:12,\\\\\“引擎子类型\\\\\”:2,\\\\“文件名\\\\”:\\\\“目标文件.csv\\”,\\\\“文件扩展类型\\\”:\\\\\\”.csv\\”,\\\\\\\\\\\\“IsLoadFile\\\”:true,\\\\\\\\\\\\\“LoadContextId\\\”:4120,\\\\\\\\\\\\“报告日期\\\”:\\\\\\\\\“2019-05-310:00:00:00:00:00\\”,\\\\\”,\\\\\\\\;
//这里失败了
var arguments=System.Text.Json.JsonSerializer.Deserialize(数据);
//这是错误的-暂时忽略
Assert.Equal(“targetFile.csv”,arguments.ToString());
}
当我在测试中调试上述内容时,它告诉我以下内容:

 var arguments = System.Text.Json.JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data).FirstOrDefault();
无法将JSON值转换为MyProject.HangfireTestDTO

然后,我的想法引导我再次尝试将反序列化行修改为以下内容:

 var arguments = System.Text.Json.JsonSerializer.Deserialize<IEnumerable<HangfireTestDTO>>(data).FirstOrDefault();
var arguments=System.Text.Json.JsonSerializer.Deserialize(data.FirstOrDefault();
但在使用新行运行时,我得到以下错误:

无法将JSON值转换为System.Collections.Generic.List


我做错了什么

第一个错误是因为
InputType
。它应该是
int

public class HangfireTestDTO
{
    public int InputType { get; set; }
    public string Filename { get; set; }
}
第二个错误是由于
JSON
。在
[
{
之间有一个附加的引号。我尝试了下面的
JSON
,它成功了。因为这个引号,它变成了
List
而不是
List

看看
JSON
应该是
IEnumerable

var arguments=JsonSerializer.Deserialize(数据);

首先,您的JSON是错误的 我也希望它看起来更像

string data = @"[{""InputType"":12,""EngineSubType"":2,""Filename"":""targetFile.csv"",""FileExtensionType"":"".csv"",""IsLoadFile"":true,""LoadContextId"":4120,""ReportingDate"":""2019-05-31T00:00:00"",""IsSuccess"":false}]"

其次,将JSON包装在[]中,这意味着一个文档列表,因此
反序列化(数据);
将是
反序列化(数据);
或其他一些IEnumerable

然后出现服务器数据不匹配12是数字而不是字符串,因此InputType应该是int或double,IsSuccess是bool,等等

最后,JSON中有很多字段不在对象上,您需要向c#解释如何处理这些字段,或者创建额外的属性,或者提供一个键值存储,它可以将这些属性放入其中 即

[JsonExtensionData]
公共字典扩展数据{get;set;}
根据您所做的注释进行编辑,如果数据确实是这样从数据库中出来的,那么它是一个字符串数组,其中的字符串是JSON编码的

在这种情况下,您需要读取字符串,然后在

var jsonlist = JsonSerializer.Deserialize<List<string>>(data);
foreach(string json in jsonlist )
    var dto = JsonSerializer.Deserialize<HangfireTestDTO>(json);
var jsonlist=JsonSerializer.Deserialize(数据);
foreach(jsonlist中的字符串json)
var dto=JsonSerializer.Deserialize(json);

您当前的JSON字符串是一个字符串数组。您需要首先将JSON反序列化为字符串列表,然后将每个字符串反序列化为DTO。以下是使用JSON的完整示例:

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Text.Json;
公共类HangfireTestDTO
{
公共int输入类型{get;set;}
公共int引擎子类型{get;set;}
公共字符串文件名{get;set;}
公共字符串FileExtensionType{get;set;}
}
班级计划
{
静态void Main()
{
字符串数据=
“[\“{\\\\\”输入类型\\\\”:12,\\\\\“引擎子类型\\\\\”:2,\\\\“文件名\\\\”:\\\\“目标文件.csv\\”,\\\\“文件扩展类型\\\”:\\\\\\”.csv\\”,\\\\\\\\\\\\“IsLoadFile\\\”:true,\\\\\\\\\\\\\“LoadContextId\\\”:4120,\\\\\\\\\\\\“报告日期\\\”:\\\\\\\\\“2019-05-310:00:00:00:00:00\\”,\\\\\”,\\\\\\\\;
//首先将单个字符串反序列化为字符串列表
List jsonStrings=JsonSerializer.Deserialize(数据);
//然后将每个字符串反序列化为DTO。
列表dtos=jsonStrings
.Select(json=>JsonSerializer.Deserialize(json))
.ToList();
控制台写入线(dtos.Count);
Console.WriteLine(dtos[0].Filename);
}
}

看起来像JSON中的JSON。尝试解析字符串列表,并分别解析这些字符串。生成JSON的任何内容都应尽快重新构造。嵌套的JSON基本上总是代码设计不好的迹象,并且在将来总是潜在的问题。@Franzgleichman,这就是hangfire。对它的零控制您已经接受了at无法处理您在问题中提出的JSON-这是否意味着您的JSON实际上不是这样?@N0xus然后告诉负责修复其代码的人,并且在他们感谢您之前不要停止告诉他们,但它会生成与我上面提到的相同错误
JSON值无法转换为System.Collections。Generic.List
1`@N0xus,很遗憾,您的json格式不正确。有一个附加引号导致了问题
[\”{
。似乎OP使用的是
System.Text.Json
,而不是
Newtonsoft.Json
@PavelAnikhouski:Ah,可以修复。但可能是几乎相同的代码。@PavelAnikhouski:Done:)Json直接从我的hangfire数据库中获取。当你将作业排队时,它会生成。对此没有任何控制权。不,你没有当你为你的测试创建数据变量的时候,有很多额外的东西
string data = "[{\"InputType\":17,\"EngineSubType\":4,\"Filename\":\"targetFile.csv\",\"FileExtensionType\":\".csv\",\"IsLoadFile\":true,\"LoadContextId\":4121,\"ReportingDate\":\"2019-05-31T00:00:00\",\"IsSuccess\":false}]"
[JsonExtensionData]
public Dictionary<string, object> ExtensionData { get; set; }
var jsonlist = JsonSerializer.Deserialize<List<string>>(data);
foreach(string json in jsonlist )
    var dto = JsonSerializer.Deserialize<HangfireTestDTO>(json);