麻烦在.NET中序列化枚举

时间:2010-07-16 15:43:53

标签: c# .net serialization enums

我在包含枚举属性的C#类的ASP.NET 2.0应用程序中使用序列化的基本硬件。我的理解是,如果它们映射到整数,则支持枚举的序列化。所以,我无法弄清楚为什么我有这个问题序列化/反序列化我的枚举。

我的代码:

[Serializable]
public class Report
{
    public PercentTime paramPercentRange;

    // Constructors
    public Report()
    {
    }
    public Report(PercentTime percentRange)
    {
        paramPercentRange = percentRange;
    }
}

public enum PercentTime
{
    Null = 0,
    ZeroToFivePercent = 1,
    FiveToTenPercent = 2,
    TenToFifteenPercent = 3,
    FifteenToTwentyPercent = 4,
    MoreThanTwentyPercent = 5
}

// Serialize Report to a HiddenField
public void SaveReportObject(Report reportObj, HiddenField hiddenReportObj)
{
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new MemoryStream();

    // Seralize Report Object to Binary Format
    formatter.Serialize(stream, reportObj);
    stream.Position = 0;

    // Convert Stream to ASCII Encoding
    StreamReader reader = new StreamReader(stream, Encoding.ASCII);

    // Store Report Object as a Base64 Encoded String in a HiddenField
    hiddenReportObj.Value = Convert.ToBase64String(Encoding.ASCII.GetBytes(reader.ReadToEnd()));

    // Close Streams
    reader.Close();
    stream.Close();
}

public Report GetReportObject(String strBase64)
{
    Report report;
    Stream stream = new MemoryStream();
    IFormatter formatter = new BinaryFormatter();
    StreamWriter writer = new StreamWriter(stream, Encoding.ASCII);
    writer.AutoFlush = true;
    stream.Position = 0;

    // Convert Base64 String to ASCII encoded Stream
    writer.Write(Encoding.ASCII.GetString(Convert.FromBase64String(strBase64)));
    stream.Position = 0;

    // Deserialze ASCII encoded Stream
    report = (Report)formatter.Deserialize(stream);  // error 

    // Close Streams
    writer.Close();
    stream.Close();

    return report;
}

我收到以下无效的BinaryFormatter错误:

   at System.Runtime.Serialization.Formatters.Binary.SizedArray.IncreaseCapacity(Int32 index)
   at System.Runtime.Serialization.Formatters.Binary.SizedArray.set_Item(Int32 index, Object value)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   at Pages_Reports_PercentTimeLobbyingReport.GetReportObject(String strBase64) 

当我查看流对象时,它的长度是287,但是位置是282.我的第一个猜测是没有读取整个流是一个问题,但是我能够更改Report类以将枚举存储为一个整数,它工作正常。我对学习这里的问题非常感兴趣。

1 个答案:

答案 0 :(得分:5)

您的信息流包含二进制数据。然后,您将其转换为 ASCII 。这是一个非常非常糟糕的主意。你会丢失数据。不要那样做。

你正在进行base64编码,但是在错误的地方。您应该将最初编写的二进制数据转换为base64,例如像这样:

string text = Convert.ToBase64String(stream.ToArray());

然后反序列化,你会反过来转换它:

IFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(text))
{
    return (Report)formatter.Deserialize(stream); 
}

我不知道为什么当你使用int时它为你工作......但我的猜测是运气比其他任何东西更多。

你永远不应该尝试阅读BinaryFormatter的输出,就好像它只是纯文本一样。