Dserialise JSON到对象。一些属性总是相同的,一些不同
我想建立一个用户可以上传json文件的功能。Dserialise JSON到对象。一些属性总是相同的,一些不同
json文件中的每一行都可以有不同的nr属性(即列)。 5这些属性总是相同的,所以我想要那些被反序列化为一个对象。其余的属性必须进入字典或其他东西。
这里是一个JSON例如:
[{
"Projekt": "Bakker Bouw Service",
"Ruimte": "Hoofdgebouw",
"Apparaat": {
"project": "Bosboom001",
"versie": "812"
},
"Apparaat naam": "",
"Status": "Goedgekeurd",
"Testname1": "",
"Testname3": "2000-01-04T10:37:00+01:00",
"Testname7": "2001-01-03T00:00:00+01:00"
}, {
"Projekt": "Bakker Bouw Service",
"Ruimte": "Hoofdgebouw",
"Apparaat": {
"project": "Vlaams003",
"versie": "713"
},
"Apparaat naam": "",
"Status": "Goedgekeurd",
"Testname1": "Slecht",
"Testname7": "2000-01-04T10:37:00+01:00",
"Testname9": "2001-01-03T00:00:00+01:00",
"Testname16": "18MOhm",
"Testname23": "OK"
}, {
"Projekt": "Bakker Bouw Service",
"Ruimte": "Hoofdgebouw",
"Apparaat": {
"project": "Vlaams017",
"versie": "73"
},
"Apparaat naam": "GDR34Z5",
"Status": "Afgekeurd",
"Testname7": "2000-01-04T10:37:00+01:00",
"Testname10": "0,012mA",
"Testname16": "200MOhm",
"Testname23": "200MOhm",
"Testname25": "Afgekeurd",
"Testname31": "0,01mA"
}
]
下面是deserialze到类:
public class KeuringRegel
{
public string Projekt { get; set; }
public string Ruimte { get; set; }
public Apparaat Apparaat { get; set; }
[JsonProperty(PropertyName = "Apparaat naam")]
public string Apparaatnaam { get; set; }
public string Status { get; set; }
public Dictionary<string, object> testNames { get; set; }
}
public class Apparaat
{
public string project { get; set; }
public string versie { get; set; }
}
这里是控制器
public IActionResult Upload(IFormFile file)
{
string fileContent = null;
using (var reader = new StreamReader(file.OpenReadStream()))
{
fileContent = reader.ReadToEnd();
}
List<KeuringRegel> keuringRegelList = JsonConvert.DeserializeObject<List<KeuringRegel>>(fileContent);
//More stuff here
}
JSON的成功反序列化,但testNames
值始终为空。我明白为什么,因为Json文件中没有testNames
属性。但是,我如何实现我想要的?我不是Json专家。你能做到这一点,假设有只有testNameNNNN
条目作为补充值
的一种方法,是使用JsonExtensionDataAttribute
这样的:
public class KeuringRegel
{
public string Projekt { get; set; }
public string Ruimte { get; set; }
public Apparaat Apparaat { get; set; }
[JsonProperty(PropertyName = "Apparaat naam")]
public string Apparaatnaam { get; set; }
public string Status { get; set; }
[JsonExtensionData()]
public Dictionary<string, object> testNames { get; set; }
}
这会给你卫生组织不属于价值成其他属性之一:
这是一个有点“钝器”,但你总是可以执行一些,生产工程过程后g在返回的KeuringRegel
实例上删除任何来自testNames的错误条目(即,与模式testNameNNNN
不匹配的东西)。
如果你的JSON 确实包含的东西不匹配,因此它会得到包括模式testNameNNNN
,你可以实现的testNames
属性自定义类:
public class KeuringRegel
{
public string Projekt { get; set; }
public string Ruimte { get; set; }
public Apparaat Apparaat { get; set; }
[JsonProperty(PropertyName = "Apparaat naam")]
public string Apparaatnaam { get; set; }
public string Status { get; set; }
[JsonExtensionData()]
public TestNames testNames { get; set; }
}
public class TestNames : Dictionary<string, object>
{
public new void Add(string key, object value)
{
if (key.StartsWith("testname", StringComparison.OrdinalIgnoreCase))
{
base.Add(key, value);
}
}
}
这将检查每一个项目是被添加到testNames
字典,并防止其添加如果(如我的评论中,我有一个项目在JSON "badgerBadgetCatCat": 3
)它不符合模式。
我正在寻找一个自定义的JsonConverter,但很快就放弃了。这是最实用的解决方案。 JSON.NET将从类属性反序列化,而不是从JSON反序列化,所以转换器永远不会看到'TestnameNN'令牌。 – CodeCaster
优秀的解决方案!谢谢!这个解决方案有没有优点和缺点?这是推荐的做事方式吗?更改JSON格式更好吗?也许是一个很好的示例文档或什么东西的链接 –
@Kipei显然,明智的做法是正确格式化生成的JSON。编号的属性是不良设计的标志。 – CodeCaster
这里u为完整的例子
internal class Program
{
private static void Main(string[] args)
{
var str = @"[{
""Projekt"": ""Bakker Bouw Service"",
""Ruimte"": ""Hoofdgebouw"",
""Apparaat"": {
""project"": ""Bosboom001"",
""versie"": ""812""
},
""Apparaat naam"": """",
""Status"": ""Goedgekeurd"",
""Testname1"": """",
""Testname3"": ""2000-01-04T10:37:00+01:00"",
""Testname7"": ""2001-01-03T00:00:00+01:00""
}, {
""Projekt"": ""Bakker Bouw Service"",
""Ruimte"": ""Hoofdgebouw"",
""Apparaat"": {
""project"": ""Vlaams003"",
""versie"": ""713""
},
""Apparaat naam"": """",
""Status"": ""Goedgekeurd"",
""Testname1"": ""Slecht"",
""Testname7"": ""2000-01-04T10:37:00+01:00"",
""Testname9"": ""2001-01-03T00:00:00+01:00"",
""Testname16"": ""18MOhm"",
""Testname23"": ""OK""
}, {
""Projekt"": ""Bakker Bouw Service"",
""Ruimte"": ""Hoofdgebouw"",
""Apparaat"": {
""project"": ""Vlaams017"",
""versie"": ""73""
},
""Apparaat naam"": ""GDR34Z5"",
""Status"": ""Afgekeurd"",
""Testname7"": ""2000-01-04T10:37:00+01:00"",
""Testname10"": ""0,012mA"",
""Testname16"": ""200MOhm"",
""Testname23"": ""200MOhm"",
""Testname25"": ""Afgekeurd"",
""Testname31"": ""0,01mA""
}
]";
var sw = Stopwatch.StartNew();
var result = Mapper.Map(str);
sw.Stop();
Console.WriteLine($"Deserialized at {sw.ElapsedMilliseconds} ms ({sw.ElapsedTicks} tiks)");
}
public static class Mapper
{
static Mapper()
{
List<string> names = new List<string>();
IEnumerable<PropertyInfo> p = typeof(KeuringRegel).GetProperties().Where(c => c.CanRead && c.CanWrite);
foreach (var propertyInfo in p)
{
var attr = propertyInfo.GetCustomAttribute<JsonPropertyAttribute>();
names.Add(attr != null ? attr.PropertyName : propertyInfo.Name);
}
Properties = names.ToArray();
}
private static string[] Properties { get; }
public static KeuringRegel[] Map(string str)
{
var keuringRegels = JsonConvert.DeserializeObject<KeuringRegel[]>(str);
var objs = JsonConvert.DeserializeObject(str) as IEnumerable;
var objectList = new List<JObject>();
foreach (JObject obj in objs)
objectList.Add(obj);
for (var i = 0; i < keuringRegels.Length; i++)
{
keuringRegels[i].testNames = new Dictionary<string, object>();
foreach (var p in objectList[i].Children().OfType<JProperty>().Where(c => !Properties.Contains(c.Name)).ToArray())
keuringRegels[i].testNames.Add(p.Name, p.Value);
}
return keuringRegels;
}
}
public class KeuringRegel
{
public string Projekt { get; set; }
public string Ruimte { get; set; }
public Apparaat Apparaat { get; set; }
[JsonProperty(PropertyName = "Apparaat naam")]
public string Apparaatnaam { get; set; }
public string Status { get; set; }
public Dictionary<string, object> testNames { get; set; }
}
public class Apparaat
{
public string project { get; set; }
public string versie { get; set; }
}
}
请解释你的方法。 – CodeCaster
这哪里是JSON建? –
https://codebeautify.org/jsonviewer –
他们可能是想问你是否可以改变JSON的格式,或者必须按原样解析它。 – CodeCaster