2010-07-16 5 views
0

J'ai un stumper élémentaire en utilisant sérialisation dans une application ASP.NET 2.0 sur une classe C# contenant une propriété ENUM. Je crois comprendre que la sérialisation des énumérations est prise en charge si elles sont mappées sur des entiers. Donc, je n'arrive pas à comprendre pourquoi j'ai ce problème sérialiser/désérialiser mon énumération.Problème sérialisation Enum dans .NET

Mon code:

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

Je reçois le texte suivant Invalid BinaryFormatter Erreur:

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) 

Quand je regarde l'objet de flux, sa longueur est de 287, mais la position est 282 Ma première supposition est que c'est un problème de ne pas lire le flux entier, mais je suis capable de changer la classe Report pour stocker l'enum comme un entier et cela fonctionne bien. Je suis très intéressé à apprendre quel est le problème ici.

+0

Merci pour la trace de la pile, mais quel était le _exception_? Postez le résultat de 'ex.ToString()'. –

Répondre

5

Votre flux contient données binaires. Vous convertissez ensuite cela en ASCII. C'est vraiment une très mauvaise idée. Vous allez perdre des données. Ne fais pas ça.

Vous faites base64, mais au mauvais endroit. Vous devez convertir les données binaires initialement écrites en base64, par exemple comme ceci:

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

Alors désérialiser, tu le convertir dans l'autre sens:

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

Je ne sais pas pourquoi il travaillait pour vous lorsque vous utilisez un int .. mais je suppose que c'était plus par chance que toute autre chose.

Vous ne devriez jamais essayer de lire la sortie d'un BinaryFormatter comme si elle était le texte brut.

+0

J'ai reconstruit avec vos changements suggérés et alto aucune erreur! Jon, tu es l'homme! – Sephrial