我正在使用泛型和自定义属性在 C# 中开发 JSON 解析器,但在将 JSON 数据正确解析到模型类中时遇到了问题。我想在不使用任何外部库的情况下实现这一目标,只需使用 .NET 的内置功能。
这是我为 JSON 创建的模型:
using System;
using System.Collections.Generic;
namespace Test3.Model
{
public class Walks
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("distance")]
public double Distance { get; set; }
[JsonProperty("duration")]
public string Duration { get; set; }
[JsonProperty("difficulty")]
public string Difficulty { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
}
}
我还创建了一个 JsonPropertyAttribute 来帮助映射:
using System;
namespace Test3
{
[AttributeUsage(AttributeTargets.Property)]
public class JsonPropertyAttribute : Attribute
{
public string Key { get; }
public JsonPropertyAttribute(string key)
{
Key = key;
}
}
}
这是我的通用 JSON 解析器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Test3
{
public class GenericJsonParser
{
public static List<T> ParseJson<T>(string json) where T : new()
{
// Logic for parsing JSON...
}
private static T ParseSingleObject<T>(string json) where T : new()
{
// Logic for parsing a single JSON object...
}
private static void SetPropertyValue<T>(T obj, string key, string value)
{
// Logic to set property value using reflection...
}
}
}
我尝试解析的 JSON 如下所示:
{
"walks": [
{
"id": 1,
"name": "River Walk",
"distance": 5.5,
"duration": "2 hours",
"difficulty": "Easy",
"description": "A scenic walk along the river with beautiful views."
},
{
"id": 2,
"name": "Mountain Trail",
"distance": 10.2,
"duration": "4 hours",
"difficulty": "Moderate",
"description": "A challenging trail through the mountains."
},
{
"id": 3,
"name": "Forest Loop",
"distance": 3.8,
"duration": "1 hour",
"difficulty": "Easy",
"description": "A peaceful walk through the forest."
}
]
}
我面临的问题:
当我尝试解析 JSON 时,我只能得到一个空的 Walk 列表。
我不确定我的解析逻辑是否使用 JsonPropertyAttribute 将属性与 JSON 键正确映射。
string json = File.ReadAllText("path_to_your_json_file");
List<Walks> walksList = GenericJsonParser.ParseJson<Walks>(json);
我不确定我的解析逻辑是否使用 JsonPropertyAttribute 将属性与 JSON 键正确映射。任何有关为什么我可能会得到空列表的帮助将不胜感激!
此结构应为其他人提供足够的背景,以了解您的情况并提供相关帮助。确保包含 JSON 文件的实际路径,并在运行解析器之前验证其格式是否正确。
正如
@Jon Skeet
提到的,主要问题可能是(我们不能确定,因为你没有提供你尝试过的解析代码),你试图解析Walks
,就好像它是json 的根对象。但是,您有一个包含数组 (Walks
) 的对象(根)。
您可以通过在现有的包装类周围添加一个包装类来解决此问题,这样您就不需要任何自定义 json 解析器,并且只需使用 .
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
public class Program
{
public class WalksWrapper
{
[JsonPropertyName("walks")]
public List<Walk> Walks { get; set; }
}
public class Walk
{
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("distance")]
public double Distance { get; set; }
[JsonPropertyName("duration")]
public string Duration { get; set; }
[JsonPropertyName("difficulty")]
public string Difficulty { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
}
public static void Main()
{
var jsonString = """
{
"walks": [
{
"id": 1,
"name": "River Walk",
"distance": 5.5,
"duration": "2 hours",
"difficulty": "Easy",
"description": "A scenic walk along the river with beautiful views."
},
{
"id": 2,
"name": "Mountain Trail",
"distance": 10.2,
"duration": "4 hours",
"difficulty": "Moderate",
"description": "A challenging trail through the mountains."
},
{
"id": 3,
"name": "Forest Loop",
"distance": 3.8,
"duration": "1 hour",
"difficulty": "Easy",
"description": "A peaceful walk through the forest."
}
]
}
""";
var walksWrapper = JsonSerializer.Deserialize<WalksWrapper>(jsonString);
// Serialize it back to JSON with the indented option for pretty printing
var prettyJson = JsonSerializer.Serialize(walksWrapper, new JsonSerializerOptions
{
WriteIndented = true
});
Console.WriteLine(prettyJson);
}
}