JSON.NET автоматически изменяет тип свойства System.Object на System.String

У меня есть класс с именем Arg, Недвижимость ArgValue имеет тип System.Object,

public class Arg
{
    public string ArgName { get; set; }
    public object ArgValue { get; set; }
}

Если я хочу десериализовать JSON-строку следующим образом:

string json = @"{""ArgName"":""arg"",""ArgValue"":""/something/more/than/a/string/""}";

var jsonSerializerSettings = new JsonSerializerSettings() { };

Arg arg = JsonConvert.DeserializeObject<Arg>(json, jsonSerializerSettings);

Я получаю объект Arg с его значениями так:

  • ArgName имеет тип string -> arg
  • ArgValue имеет тип object {string} -> /something/more/than/a/string/

Я не хочу, чтобы JSON.NET преобразовывал его в System.String, Если свойство имеет тип System.Object это не должно преобразовывать это в строку.

Было бы лучше, если бы он оставался нетронутым, а значение имело бы тип: JToken (или JValue).

Есть ли опция JsonSerializerSettings для настройки этого поведения?

Дополнительная информация:

Строковое значение в свойстве ArgValue "больше, чем строка", и мне нужно преобразовать его позже самостоятельно. JsonConverter не может быть использован здесь, потому что я не знаю конкретный тип объекта на данный момент. позже я знаю и нужно использовать JToken.ToObject<MySpecialType>(), (Чем он правильно конвертируется JsonConverter).

2 ответа

Как я уже говорил в комментарии, строка json, которую вы хотите десериализовать, будет десериализована в объект класса с двумя свойствами, оба типа string. Это потому, что когда вы указываете "ArgName" : "arg" две цитаты между arg отметить значение типа строки. Это также случай ArgValue который сериализуется также в виде строки.

Делая эту строку кода:

Arg arg = JsonConvert.DeserializeObject<Arg>(json, jsonSerializerSettings);

Вы получаете объект (arg) типа Arg который в точности как классический объект типа Arg, Это эквивалентно выполнению:

Arg arg = new Arg{ ArgName = "arg", ArgValue = "/something/more/than/a/string/" };

Строка присваивания свойства ArgValue который ожидает, что объект будет таким же в случае десериализации, это не конверсия (или, что лучше сказать, приведение), это только бокс.

Для последующего преобразования вы можете использовать

Дженерики

public class Arg<T>
{
    public string ArgName { get; set; }
    public T ArgValue { get; set; }
}

тогда вы можете передать тип цели следующим образом:

JsonConvert.DeserializeObject<Arg<Qualifiedname>>(somestring);

или же

public Arg<T> Deserialize<T>(string somestring){
  return JsonConvert.DeserializeObject<Arg<T>>(somestring);
}

Оставь это как JToken

public class Arg
{
    public string ArgName { get; set; }
    public JToken ArgValue { get; set; }
}

Десериализовать это позже с JsonConvert

public class Arg
{
    public string ArgName { get; set; }
    public string ArgValue { get; set; }
}

или просто передайте его целиком как строку, пока не узнаете, какой тип будет проанализирован..

Другие вопросы по тегам