简体   繁体   中英

How to serialize / deserialize RestSharp RestRequest

I am using RestSharp as HTTP API Client for my Silverlight project. If there is no internet connection, I want to serialize rest request object in the form of string and save it to local storage. When internet connection is up, I'll deserialize that string, get original the object and send request again. So far I tried following ways to serialize / deserialize rest request object:

1) Silverlight serializer : It could serialize some rest requests. But for certain types of requests it throws System.ArgumentException while serializing object. Below are exception details:

Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

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 : It throws System.Runtime.Serialization.SerializationException while serializing object. Here are exception details:

Type 'RestSharp.Serializers.JsonSerializer' with data contract name 'JsonSerializer: http://schemas.datacontract.org/2004/07/RestSharp.Serializers ' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to 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;
    }
}

After a lot of investigation, I've not been able to find out exception-proof ways to serialize / deserialize rest request objects. Could anybody find glitch in my code? Any help will be appreciated.

Have you tried protobuf-net ? It's a .NET implementation of Google's super-efficient protocol buffers, written by Marc Gravel and used at Stack Exchange. Much faster/cheaper/smaller than XML serialization, and at according to the docs Silverlight is supported.

If protobuf doesn't work, I'd honestly give up and define a custom class that can be serialized to store everything you need to reconstruct a RestRequest object. Something like:

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

Then write your serialization code against that type and add a pair of methods to map from RestRequest to RestRequestData and vice-versa.

Probably not the answer you were hoping for, but RestRequest holds hard references serializer objects and lots of other stuff and was probably simply not designed with serialization in mind.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM