Json.Net中字符串列表为CSV字符串

时间:2017-07-24 14:23:30

标签: c# json.net

我想知道是否可以使用Json.Net将任何document.addEventListener( 'load', function(event){ var elm = event.target; if( elm.id === 'iframe'){ // or any other filtering condition console.log("Sure iframe is loaded!") } }, true // Capture event ); 序列化和反序列化为C#中逗号分隔值的字符串:

List<string>

我怎样才能实现代码中的注释反映?

实现自定义class MyDTO { public int Age { get; set; } = 25; public string Name { get; set; } = "Jon"; public List<string> Friends { get; set; } = new List<string> {"Jan", "Joe", "Tim"}; } var serilalized = JsonConvert.SerializeObject(new MyDTO()); //serialized = { "name": "Jon", "age": 25, "friends": "Jan,Joe,Tim" } var deserialized = JsonConvert.DeserializeObject<MyDTO>(serialized); //deserialized.Name = "Jon", deserialized.Age = 25, deserialized.Friends = List<string> {"Jan", "Joe", "Tim"} 是解决此问题的一个很好的解决方案,但是当我使用非泛型版本JsonConverter反序列化时,JsonConverter没有效果,并且反序列化的值具有类型{{1} },而不是我想要的类型JsonConvert.DeserializeObject(serialized)。例如:

JTokenType.String

我希望上面的代码可以在第一种情况下打印JTokenType.Array,在第二种情况下打印JObject obj = (JObject)JsonConvert.DeserializeObject(serilalized); JToken token = obj["friends"]; Console.WriteLine(token.Type == JTokenType.String); //prints true Console.WriteLine(token.Type == JTokenType.Array); //prints false 。请注意,在反序列化时,我没有可用的类型false

2 个答案:

答案 0 :(得分:3)

我不确定你为什么需要这个,但你可以做一个简单的JsonConverter来做你想做的事情:

public class ListToCsvConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<string>);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(string.Join(",", (List<string>)value));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return new List<string>(((string)reader.Value).Split(','));
    }
}

然后将[JsonConverter]属性添加到您希望由转换器处理的类的list属性中:

class MyDTO
{
    [JsonConverter(typeof(ListToCsvConverter))]
    public List<string> Friends { get; set; } = new List<string> { "Jan", "Joe", "Tim" };
}

当然,此解决方案假定您的所有字符串都不会包含逗号。如果你的字符串可以包含逗号,那么你需要一个逗号的转义机制来确保成功的往返。那时我建议坚持使用默认序列化,因为JSON已经有了这样的机制。

往返演示:https://dotnetfiddle.net/dVh4Zq

如果您没有可用于反序列化的DTO,则必须使用JObject并且您将无法使用上述转换器。相反,您可以使用辅助方法在反序列化后将包含CSV字符串的JToken转换为JArray

static JArray ConvertCsvToArray(JToken value)
{
    if (value.Type == JTokenType.String)
    {
        return JArray.FromObject(((string)value).Split(','));
    }
    throw new ArgumentException("The token does not contain a string value.");
}

像这样使用:

JObject obj = (JObject)JsonConvert.DeserializeObject(serialized);

JArray array = ConvertCsvToArray(obj["friends"]);

答案 1 :(得分:0)

如果你在调试器中查看serilalized,它看起来像这样:

"{\"Age\":25,\"Name\":\"Jon\",\"Friends\":[\"Jan\",\"Joe\",\"Tim\"]}"

这是因为serilalized是一个字符串,并且该字符串中嵌入了"

当打印到控制台时,它看起来像这样:

{"Age":25,"Name":"Jon","Friends":["Jan","Joe","Tim"]}

哪一项完全正确(FriendsString的列表)。

这里唯一的问题是你初始化Friends并且反序列化添加,导致6个条目而不是3个。

如果您认为确实需要将Friends序列化为一串逗号分隔值(我不建议这样做),您需要查看JsonConverter

更新:请注意,这不适用于反序列化为JObject(因为您现在已经表明了您的需要)。您需要查找带逗号的字符串和.Split目标对象的字符串(假设所有带逗号的字符串都应该是字符串列表)。 OR 只是像以前一样序列化,你得到一个带有字符串的JArray。这正是我不建议您尝试这样做的原因:数据的非标准表示。