我正在尝试在反序列化期间将一个带有例如[1,2,3]的json字符串解析为数组。
这是我的json数据:
[
{
"id": "1",
"district": "1",
"lon": "4.420650000000000000",
"lat": "51.21782000000000000",
"bikes": "19",
"slots": "14",
"zip": "2018",
"address": "Koningin Astridplein",
"addressNumber": null,
"nearbyStations": "3,4,5,24",
"status": "OPN",
"name": "001- Centraal Station - Astrid"
}
]
这是我的c#当前映射到常规字符串,我希望它是一个整数数组。
var AvailabilityMap = new[] { new Station() };
var data = JsonConvert.DeserializeAnonymousType(json, AvailabilityMap);
public class Station
{
public int Id { get; set; }
public double Lon { get; set; }
public double Lat { get; set; }
public int Bikes { get; set; }
public int Slots { get; set; }
public string Address { get; set; }
public string NearbyStations { get; set; }
public string Status { get; set; }
public string Name { get; set; }
}
到目前为止,我没有找到以正确方式执行此操作的方法,而无需再次循环使用当前数组..
答案 0 :(得分:4)
创建自定义转换器。像这样:
PropertyChangedHandler
现在更改您的课程以使用aViewModel.OnPropertyChanged(
handler: p => FooBarBazCommand.Invalidate(),
properties: aViewModel.GetProperties(
p => p.Foo,
p => p.Bar,
p => p.Baz
)
);
:
public class StringToIntEnumerable : JsonConverter
{
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}
public override bool CanWrite
{
get
{
return false; // we'll stick to read-only. If you want to be able
// to write it isn't that much harder to do.
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Note: I've skipped over a lot of error checking and trapping here
// but you might want to add some
var str = reader.Value.ToString();
return str.Split(',').Select(s => int.Parse(s));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
现在要反序列化:
JsonConverterAttribute
答案 1 :(得分:2)
Here is a working fiddle使用自定义JsonConverter
。
我们正在做的是在将整个JSON字符串转换为Station
对象之前,将CSV值转换为正确的JSON数组。
JsonConverter
ReadJson
读取JSON字符串。首先,它将JSON加载到JObject
。接下来,它获取nearbyStations
属性并将其从简单的CSV字符串更改为JavaScript数组。它通过将CSV包装在方括号内来实现。最后,我们使用JsonSerializer
填充目标对象并将其返回。
CanWrite
设置为false
,因为此JsonConverter
只允许读取JSON而不是写入JSON。因此,我们不需要实施WriteJson
。 CanConvert
测试以确保目标对象是Station
。
public class StationConverter : JsonConverter
{
public override object ReadJson(
JsonReader r, Type t, object v, JsonSerializer s)
{
JObject jObject = JObject.Load(r);
var prop = jObject.Property("nearbyStations");
var wrapped = string.Format("[{0}]", prop.Value);
JArray jsonArray = JArray.Parse(wrapped);
prop.Value = jsonArray;
var target = new Station();
s.Populate(jObject.CreateReader(), target);
return target;
}
public override void WriteJson(JsonWriter w, object v, JsonSerializer s)
{
throw new NotImplementedException("Unnecessary: CanWrite is false.");
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof (Station);
}
}
Station
类更改为int[]
要使上述JsonConverter
生效,请将您的NearbyStations
媒体资源更改为int[]
。
public int[] NearbyStations
{
get;
set;
}
以下是如何使用它的示例:
var AvailabilityMap =
JsonConvert.DeserializeObject<Station[]>(json, new StationConverter());
Console.WriteLine(AvailabilityMap[0].NearbyStations[0]);
答案 2 :(得分:1)
正确的答案是输入格式正确。在这种情况下:
"nearbyStations": ["3","4","5","24"]
但我遇到了类似无法更新数据的情况,因此必须找到解决方案。最简单的方法是制作一个不会被串行器/解串器触及的getter / setter。不幸的是,您无法使用此序列化程序忽略公共属性。所以你必须做一些聪明的解决方法,比如阅读DTO并使用业务对象进行实际操作。
public class StationDTO
{
public int Id { get; set; }
public double Lon { get; set; }
public double Lat { get; set; }
public int Bikes { get; set; }
public int Slots { get; set; }
public string Address { get; set; }
public string NearbyStations { get; set; }
public string Status { get; set; }
public string Name { get; set; }
}
...
public class Station : StationDTO
{
public List<string> NearbyStationsList
{
get
{
return NearbyStations.Split(',');
}
set
{
NearbyStations = string.Join(",", value);
}
}
}