Member 7677029 Ответов: 2

C#- десериализация json в объект


Hi..I have an issue with json serialization which throws the error: 

"Could not cast or convert from System.String to System.Collections.Generic.IList`1[System.String].]".
 
My json: "{\"Type\": \"abc\",\"Filepath\": \"D:\\\\abc.doc\"}"; 
My class: 
public class Arguments { public string Type { get; set; } 
public IList Filepath { get; set; } } 
My code to deserialize: 
var jsonObj = new JavaScriptSerializer().Deserialize(json); 

Can you help me understand the issue? I have made it a list as there can be situation to receive multiple objects and hence it is required. Would be great if you can help me!

It works fine when i have multiple values, ie:
 "{\"Type\": \"abc\",\"Filepath\": [\"D:\\\\abc1.doc\",\"D:\\\\abc2.doc\"]}";
I want it to work fine in both ways.


Что я уже пробовал:

My code to deserialize: 
var jsonObj = new JavaScriptSerializer().Deserialize(json); 

2 Ответов

Рейтинг:
12

Graeme_Grant

Ладно, это

{
    "Type": "abc",
    "Filepath": "D:\\abc.doc"
}

десериализуется до этого:
public class Example
{
    public string Type { get; set; }
    public string Filepath { get; set; }
}

А это
{
    "Type": "abc",
    "Filepath": ["D:\\abc1.doc","D:\\abc2.doc"]
}

десериализуется до этого:
public class Example
{
    public string Type { get; set; }
    public IList<string> Filepath { get; set; }
}

Итак, ошибка, которую вы видите:
"Could not cast or convert from System.String to System.Collections.Generic.IList`1[System.String].]".

Теперь это должно иметь больше смысла. Так вы не может десериализовать этот:
{
    "Type": "abc",
    "Filepath": "D:\\abc.doc"
}

до настоящего времени:
public class Example
{
    public string Type { get; set; }
    public IList<string> Filepath { get; set; }
}

Для получения дополнительной информации о работе с десериализацией JSON ознакомьтесь с этой статьей: Работа с JSON в C# и VB[^]


Richard Deeming

Вы мочь десериализуйте его, если вы используете JSON.NET с помощью специального конвертера. :)

Graeme_Grant

Да, вы можете, и я почти включил конвертер. Но я чувствовал, основываясь на вопросе, что это был технически неправильный ответ и слишком продвинутый для операции. Связанная статья действительно очень подробно описывает пользовательские конвертеры.:)

Member 7677029

Спасибо за ответ!

Graeme_Grant

Мы всегда рады вам :)

Рейтинг:
1

Richard Deeming

Это ужасная схема JSON. Вам придется использовать JSON.NET[^] с пользовательским конвертером для его чтения.

Этот поток StackOverflow[^] есть пример:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Array)
        {
            return token.ToObject<List<T>>();
        }
        return new List<T> { token.ToObject<T>() };
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        List<T> list = (List<T>)value;
        if (list.Count == 1)
        {
            value = list[0];
        }
        serializer.Serialize(writer, value);
    }
}

...

[JsonConverter(typeof(SingleOrArrayConverter<string>))]
public List<string> Filepath { get; set; }


Member 7677029

Спасибо за ответ, однако я не могу использовать json.net :(

Richard Deeming

Вам нужно будет заставить человека, который генерирует JSON, исправить свою схему так, чтобы она всегда отправляла массив. То JavaScriptSerializer класс не может справиться со свойством, являющимся либо массивом, либо одним значением.

Graeme_Grant

5 б