Как сериализовать/десериализовать RestSharp RestRequest

Я использую RestSharp в качестве клиента HTTP API для своего проекта Silverlight. Если нет подключения к Интернету, я хочу сериализовать объект запроса отдыха в виде строки и сохранить его в локальном хранилище. Когда подключение к Интернету установлено, я десериализую эту строку, получу исходный объект и снова отправлю запрос. До сих пор я пробовал следующие способы сериализации/десериализации объекта запроса остатка:

1) Сериализатор Silverlight: он может сериализовать некоторые запросы на отдых. Но для определенных типов запросов он генерирует System.ArgumentException при сериализации объекта. Ниже приведены сведения об исключении:

Смещение и длина вышли за пределы допустимого для массива или количество элементов больше, чем количество элементов от индекса до конца исходной коллекции.

public static string Serialize(object objectToSerialize)
{
      byte[] serializedBytes = SilverlightSerializer.Serialize(objectToSerialize);
      var serializedCharacters = new char[serializedBytes.Length/sizeof (char)];
      Buffer.BlockCopy(serializedBytes, 0, serializedCharacters, 0, serializedBytes.Length);
      return new string(serializedCharacters);
}

public static T Deserialize<T>(string serializedString) where T : class
{
       var serializedBytes = new byte[serializedString.Length*sizeof (char)];
       Buffer.BlockCopy(serializedString.ToCharArray(), 0, serializedBytes, 0, serializedBytes.Length);
       return SilverlightSerializer.Deserialize<T>(serializedBytes);
}

2) DataContractSerializer: генерирует System.Runtime.Serialization.SerializationException при сериализации объекта. Вот подробности исключения:

Введите «RestSharp.Serializers.JsonSerializer» с именем контракта данных «JsonSerializer:http://schemas.datacontract.org/2004/07/RestSharp.Serializers' не ожидается. Добавьте все типы, которые не известны статически, в список известных типов, например, с помощью атрибута KnownTypeAttribute или путем добавления их в список известных типов, переданный в DataContractSerializer.

public static string Serialize(object objectToSerialize)
{
    try
    {
        var dataContractSerializer = new DataContractSerializer(objectToSerialize.GetType());
        var memoryStream = new MemoryStream();
        dataContractSerializer.WriteObject(memoryStream, objectToSerialize);
        return Encoding.UTF8.GetString(memoryStream.GetBuffer(), 0, (int) memoryStream.Position);
    }
    catch (Exception exception)
    {
        MessageBox.Show("Message:\n" + exception.Message + "\nStackTrace:\n" + exception.StackTrace,
            "Error in serialization", MessageBoxButton.OK);
        throw;
    }
}

public static T Deserialize<T>(string serializedString) where T : class
{
    try
    {
        var dataContractSerializer = new DataContractSerializer(typeof (T));
        var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(serializedString));
        return (T) dataContractSerializer.ReadObject(memoryStream);
    }
    catch (Exception exception)
    {
        MessageBox.Show("Message:\n" + exception.Message + "\nStackTrace:\n" + exception.StackTrace,
            "Error in deserialization", MessageBoxButton.OK);
        throw;
    }
}

После долгих исследований я не смог найти защищенные от исключений способы сериализации/десериализации объектов остальных запросов. Может ли кто-нибудь найти ошибку в моем коде? Любая помощь будет оценена.


person Tejas Sutar    schedule 19.06.2014    source источник
comment
Должно быть что-то в моделях (типах). Вы пытаетесь десериализовать XML в JSON?   -  person Faisal    schedule 19.06.2014


Ответы (2)


Пробовали ли вы protobuf-net? Это .NET-реализация сверхэффективных буферов протокола Google, написанная Марком Гравелом и используемая в Stack Exchange. Гораздо быстрее/дешевле/меньше, чем сериализация XML, и в соответствии с документами поддерживается Silverlight.

person Todd Menier    schedule 22.06.2014

Если protobuf не работает, я бы честно сдался и определил собственный класс, который можно сериализовать для хранения всего необходимого для восстановления объекта RestRequest. Что-то типа:

public class RestRequestData
{
    public HttpMethod HttpMethod { get; set; }
    public object ContentData { get; set; }
    public IDictionary Headers { get; set; }
    // whatever else is needed
}

Затем напишите свой код сериализации для этого типа и добавьте пару методов для сопоставления RestRequest с RestRequestData и наоборот.

Вероятно, это не тот ответ, на который вы надеялись, но RestRequest содержит объекты сериализатора жестких ссылок и множество других вещей и, вероятно, просто не был разработан с учетом сериализации.

person Todd Menier    schedule 22.06.2014