Я нашел множество уродливых решений для этого, но до сих пор идет речь:
Если вы используете System.Web.Script.Serialization.JavaScriptSerializer
, у вас очень ограниченный контроль.Если тип данных результата прост, вы можете просто использовать метод DeserializeObject
;он переведет все в словарь, и свойство «resultObject» в первом случае будет словарём, а во втором случае оно превратится в массив такого словаря.Это не избавит вас от головной боли при окончательном переводе, но вы получите данные в словарях, которые можно считать первым шагом.
Я также попытался использовать KnownTypes и DataContractJsonSerializer, но, увы, сериализатор данныхнуждается в «подсказках» в форме специально названных свойств, чтобы помочь его десериализации.( Почему я неправильно использую атрибут KnownType? ).Это безнадежная стратегия, если вы не имеете никакого контроля над сериализацией, что, я думаю, имеет место для вас.
Итак, теперь мы подошли к уродливым решениям, выбор которых методом проб и ошибок является моим первым выбором: при использовании ScriptSerializer преобразование завершится неудачно с InvalidOperationException, если что-то не так.Затем я создал два типа данных, один с массивами данных, а другой - с данными как единым экземпляром (DataClass - мое изобретение, поскольку вы не указываете типы данных):
[DataContract]
public class DataClass
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public int BirthYear { get; set; }
public override string ToString()
{
return "FirstName : '" + FirstName + "', BirthYear: " + BirthYear;
}
}
[DataContract]
public class ResultSingle
{
[DataMember]
public DataClass Data { get; set; }
}
[DataContract]
public class ResultArray
{
[DataMember]
public List<DataClass> Data { get; set; }
}
Использование этих типов данныхперевод можно выполнить с помощью
JavaScriptSerializer jSer = new JavaScriptSerializer();
var one = jSer.Deserialize<ResultSingle>(jsonWithSingleInstance);
var many = jSer.Deserialize<ResultArray>(jsonWithArray);
Но для этого, конечно, необходимо заранее знать тип данных, и вы получите два разных типа результатов.Вместо этого вы можете всегда конвертировать в ResultArray.Если вы получили исключение, вы должны преобразовать как ResultSingle, а затем создать экземпляр ResultArray и вручную добавить объект данных в список данных:
static ResultArray ConvertJson(string json)
{
ResultArray fromJson;
JavaScriptSerializer jSer = new JavaScriptSerializer();
try
{
fromJson = jSer.Deserialize<ResultArray>(json);
return fromJson;
}
catch (InvalidOperationException)
{
var single = jSer.Deserialize<ResultSingle> (json);
fromJson = new ResultArray();
fromJson.Data = new List<DataClass>();
fromJson.Data.Add(single.Data);
return fromJson;
}
}
static void Main(string[] args)
{
var jsonWithSingleInstance = "{\"Data\":{\"FirstName\":\"Knud\",\"BirthYear\":1928}}";
var jsonWithArray = "{\"Data\":[{\"FirstName\":\"Knud\",\"BirthYear\":1928},{\"FirstName\":\"Svend\",\"BirthYear\":1930}]}";
var single = ConvertJson(jsonWithSingleInstance);
var array = ConvertJson(jsonWithArray);
}
Я не говорю, что это красивое решение (это не так), но это должно сработать.
Вы также можете посмотреть на json.net, который, кажется, является предпочтительным сериализатором json в .NET: Как установить JSON.NET с помощью NuGet?