C#对象转字符串和反向转换

14

我的问题:
我有一个动态代码编译器,可以编译一段代码片段,但其余的代码(导入、名称空间、类、主函数)已经存在。该代码片段被插入其中,然后编译成汇编并执行。这是用户执行代码片段的方式。主函数(其中代码片段被执行)具有对象返回类型。此片段在远程计算机上执行。客户端将代码发送到Web服务器。远程计算机从Web服务器读取代码并执行它。在远程计算机上,我可以轻松查看返回对象的类型及其值。但是,我只能向Web服务器发送字符串。

问题:
如何将对象转换为字符串,无论其类型如何,以及如何将其转换回来?

尝试过:
我尝试使用ToString(),对于int、string、double和bool等类型,这样做可以正常工作。但是对于图像或其他类型,则不能使用此方法,因为我还需要能够将其转换回去。


6
你要找的是叫做序列化的技术 - 在这个网站搜索这个词,你会找到大量相关信息。 - Oded
3个回答

21

使用BinaryFormatter对对象进行序列化,然后将字节作为字符串返回(Base64编码)。反向操作可以还原出对象。

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);
   }
}

1
当然,这假设对象使用BinaryFormatter是可序列化的。此外,BinaryFormatter让我哭泣;p 但它确实回答了这个问题... - Marc Gravell
为什么这会让你哭泣?有什么特别的原因吗? - Kirk
@Kirk 有很多帮助人们调试 BinaryFormatter 的经验 ;p 我在这里提到了其中一些:http://stackoverflow.com/questions/6979153/is-there-a-way-to-make-a-query-that-looks-in-serialized-binary-object-in-sql-serv/6979632#6979632 - 但是 Anders 是对的 - 只要这个连接的两端始终保持同步,它就应该可以正常工作。问题主要出现在用于存储时,或者不能保证两个端点处于相同版本时。 - Marc Gravell
在示例中添加了一个 using 语句。 - Anders Forsgren
而且StringToObject方法可以缩短。- 抱歉,我有优化代码的习惯。 - string.Empty
显示剩余5条评论

9

这是一个老问题,但我认为我有一个更好的解决方案(它创建了一个更短的字符串,并且不需要 Serializable 属性)。

思路是将对象序列化为 JSON,然后将其转换为 base64,参见以下扩展函数:

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

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

    return Convert.ToBase64String(bytes);
}

为了创建对象,我们需要将base64转换为字节,再将其转换为字符串,并反序列化JSON为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);
}

0

你需要编写一个转换方法来显示并序列化它,以便能够进行前后转换。

例如:

    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();
        }
    }

@Marc 嗯,也许Session更好? - Oskar Kjellin
@Oskar 不,我只是想说:我不确定这个问题与 ViewData/Session 等类似的东西有什么关系——它似乎是一个简单的序列化问题... - Marc Gravell
@Marc 嗯,我猜他正在使用asp.Net web来执行代码。在这种情况下,您可以使用会话来存储对象。 - Oskar Kjellin
只是字符串被发布到一个网页上,该网页将其存储在文本文件中。服务器从该文件中读取。 - Kirk
@Marc,那么“Session”部分就不相关了。思路是以一种方式展示对象,并将对象保留在会话中而无需将其转换为字符串。但如果需要将它写入文本文件,则不可能实现。 - Oskar Kjellin
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接