14

My problem:
I have a dynamic codecompiler which can compile a snippet of code. The rest of the code. (imports, namespace, class, main function) is already there. The snippet get inserted into that and then it is compiled to an assembly and executed. This is how user is able execute code snippet. The main function (where the snippet is executed) has a return type of object. This snippet gets executed on a remote computer. The code is send by the client to a webserver. The remote computer reads out the code from the webserver and executes it. On the remote computer I can easily view the type of the returned object and its value. However I can only send strings to the webserver.

Question:
How do I convert a object into a string, no matter what the type is and how do I convert it back?

Tried:
I tried using ToString(), that works fine when using int, string, double and bool. But with an image or an other type is doesn't work of course because I also need to able to convert it back.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Kirk
  • 149
  • 1
  • 1
  • 3
  • 6
    What you are looking for is called **serialization** - search for that term in this site and you will find lots of information. – Oded Aug 08 '11 at 08:57

3 Answers3

22

Serialize the object using the BinaryFormatter, and then return the bytes as a string (Base64 encoded). Doing it backwards gives you your object back.

public string ObjectToString(object obj)
{
   using (MemoryStream ms = new MemoryStream())
   {
     new BinaryFormatter().Serialize(ms, obj);         
     return Convert.ToBase64String(ms.ToArray());
   }
}

public object StringToObject(string base64String)
{    
   byte[] bytes = Convert.FromBase64String(base64String);
   using (MemoryStream ms = new MemoryStream(bytes, 0, bytes.Length))
   {
      ms.Write(bytes, 0, bytes.Length);
      ms.Position = 0;
      return new BinaryFormatter().Deserialize(ms);
   }
}
Anders Forsgren
  • 10,827
  • 4
  • 40
  • 77
  • 1
    This of course assumes that the objects are serializable with `BinaryFormatter`. Plus `BinaryFormatter` makes me weep ;p But it does address the question... – Marc Gravell Aug 08 '11 at 09:11
  • Marc, I know :) But given there is no versioning or persistence (that would warrant the use of another serialization technique) the binaryformatter (and pretty much *only the binary formatter) works. Deep cloning, communication between instances of the same app etc. are perfect fits for BF, assuming that you want to pass any object. The restriction of everything [Serializable] is basically the smallest restriction you can have. – Anders Forsgren Aug 08 '11 at 09:14
  • Why does it make you go weep? Any particulair reason? – Kirk Aug 08 '11 at 09:14
  • @Kirk lots of experiences of helping people debug the evil that BinaryFormatter makes ;p I mention some of these here: http://stackoverflow.com/questions/6979153/is-there-a-way-to-make-a-query-that-looks-in-serialized-binary-object-in-sql-serv/6979632#6979632 - but Anders is right - as long as the two ends of this connection are always in sync, it should work fine. Problems come *mainly* when used for storage, or when the 2 endpoints can't be guaranteed to be at the same version. – Marc Gravell Aug 08 '11 at 09:19
  • Got an exception with stringtoobject. Doing ms.Position = 0; before returning fixed it. – Kirk Aug 08 '11 at 11:22
  • Edited the answer to include Position = 0. – Anders Forsgren Aug 08 '11 at 11:32
  • Added a `using` clause to the example. – Anders Forsgren Aug 19 '13 at 07:54
  • And the StringToObject method can be shortened. - Sorry i have this habit of optimizing my code. – string.Empty Sep 04 '13 at 05:57
  • These methods are obsolete, and we cant use them. https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/binaryformatter-serialization-obsolete – Moslem Hadi Feb 01 '23 at 05:40
  • Yes as far as I know there is no serializer in .NET that does what BinaryFormatter did in .NET Framework (for better or worse). I.e. that it can roundtrip anything without more setup than an attribute, and none of the limitations that you might get from e.g. using JSON. I'd try json first and see if that i enough, and if not, then I'd try Protobuf or a similar format. – Anders Forsgren Feb 01 '23 at 16:03
8

It's an old question but I think that I have a solution that can work better for most of the times (it creates a shorter string and doesn't require the Serializable attribute).

The idea is to serialize the object to JSON and then convert it to base64, see the extension function:

public static string ToBase64(this object obj)
{
    string json = JsonConvert.SerializeObject(obj);

    byte[] bytes = Encoding.Default.GetBytes(json);

    return Convert.ToBase64String(bytes);
}

In order to create the object, we need to convert the base64 to bytes, convert to string and deserialize the JSON to T

public static T FromBase64<T>(this string base64Text)
{
    byte[] bytes = Convert.FromBase64String(base64Text);

    string json = Encoding.Default.GetString(bytes);

    return JsonConvert.DeserializeObject<T>(json);
}
Aharon Ohayon
  • 1,171
  • 1
  • 17
  • 20
0

You will have to make a conversion method to display it and serialize it to be able to convert it back and forth.

For instance:

    public static string ConvertToDisplayString(object o)
    {
        if (o == null)
            return "null";
        var type = o.GetType();
        if (type == typeof(YourType))
        {
            return ((YourType)o).Property;
        }
        else
        {
            return o.ToString();
        }
    }
Oskar Kjellin
  • 21,280
  • 10
  • 54
  • 93
  • @Marc hmm, `Session` might be better? – Oskar Kjellin Aug 08 '11 at 09:05
  • Exactly how I was thinking. But how do I convert it back in case of a bitmap? I already read up some stuff about xml serialization but you cant do it with an image.. I thought converting to a base64 string?? – Kirk Aug 08 '11 at 09:08
  • You can convert it to base64 just as @Anders proposed. If you store it in the session you can get the object that way as well – Oskar Kjellin Aug 08 '11 at 09:09
  • @Oskar no, I simply meant: I'm not sure how the question relates to things *like* ViewData/Session - it seems a straight serialization question... – Marc Gravell Aug 08 '11 at 09:10
  • @Marc Well, I just guessed he is using asp.Net web to execute the code. In that case you could use the session to store the object – Oskar Kjellin Aug 08 '11 at 09:12
  • maybe (subjective), but the *question* doesn't seem to be related to storage. – Marc Gravell Aug 08 '11 at 09:17
  • Nahh just the srtring gets posted to a webpage wich stores it in a text file. Server reads from that file. – Kirk Aug 08 '11 at 09:17
  • @Marc Well, then the Session part is not relevant. The idea was to display the object in one way and just keep the object alive in the session without converting it to strings. But if it needs to be written to a text file then it ain't possible – Oskar Kjellin Aug 08 '11 at 09:35