Avatar billede brooks Nybegynder
09. april 2003 - 10:09 Der er 9 kommentarer og
1 løsning

En SerializationException hvorfor?

Jeg har et problem med at serialize exception objecter.

I det konkrete tilfælde drejer det sig om en HttpException, som smider en SerializationException, når jeg prøver at serialize den (!).

Et stykke kode:
1) Exception exception = new HttpException("tester");

2) IFormatter formatter = new BinaryFormatter();
3) System.IO.MemoryStream myStream = new System.IO.MemoryStream();
4) formatter.Serialize( myStream, exception );

I linie 4 kommer der en SerializationException med message: "The type System.Web.HttpException in Assembly System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a is not marked as serializable."

Hvis man kigger i dokumentationen, så er HttpException serializable, og hvis man kigger nærmere på den med reflection kan man se at faktisk implementere ISerializable (prøv f.eks. med WinCV tool'et). Udtrykket (exception is ISerializable) evaluerer til sandt...

Hvis jeg i ovenstående kode ændrer exception typen til "Exception" (linie 1) virker det. Det hjælper ikke at typecaste til hverken Exception eller ISerializable i
linie 4 (selvom begge casts lykkedes).

Kigger man nærmere på den exception i debuggeren, så er alle referencer til eksterne objecter null (f.eks. InnerException, TargetSite, ExceptionMethod etc.) så det er næppe fordi jeg er afhængig af objekter der ikke er serializable...

Ovenstående er kompileret i et console project, men resultatet er det samme i et ASP.NET project (hvis du altså fanger den exception).

Nu synes jeg snart jeg har undersøgt alt hvad jeg kan komme i tanke om, HJÆLP!
Avatar billede z42cool Nybegynder
09. april 2003 - 10:20 #1
SerializableAttribute attributten arves ikke og da HttpException ikke er markeret [Serializable] er den det ikke.
Avatar billede z42cool Nybegynder
09. april 2003 - 10:21 #2
Ydermere, hvis du kigger i dokumentationen vil du se at HttpException blot arver  Exception klassens implementering af ISerializable.GetObjectData og altså ikke selv supplerer en implementation af GetObjectData.
Avatar billede brooks Nybegynder
09. april 2003 - 11:30 #3
Ja du har ret. Desværre løser det jo kun mit problem delvist.

Jeg har jo stadig ikke fået serializet min exception. Jeg arbejder med at udnytte at HttpException nedarver fra ISerializable, som følger:

Exception exception = new HttpException("tester");

SerializationInfo sinfo = new SerializationInfo( typeof( HttpException ), new FormatterConverter() );
StreamingContext sctx = new StreamingContext( StreamingContextStates.All );

exception.GetObjectData( sinfo, sctx );

foreach(SerializationEntry val in sinfo){
console.WriteLine("name:{0}, type:{1}, val:{2}", val.Name, val.ObjectType,  val.Value);
}

... skriv det til en fil
Avatar billede z42cool Nybegynder
09. april 2003 - 11:32 #4
Der er ikke nogen værdier i en HttpException der er context afhængige så hvis du selv står for serialiseringen tror jeg ikke det bliver noget problem!
Avatar billede brooks Nybegynder
09. april 2003 - 11:33 #5
Men anyway, så er det en tåbelig bug i frameworket. Nogen der ved om den er rettet i version 1.1???
Avatar billede burningice Nybegynder
09. april 2003 - 12:20 #6
brooks>> hvorfor subclasser du ikke bare HttpException og laver den serializerbar.
Avatar billede z42cool Nybegynder
09. april 2003 - 12:32 #7
cyberfessor>> Det nytte jo kun hvis alle de HttpExceptions han ønsker at serialisere er kastet af ham selv, ellers skal han overtale de "andre" klasser til at instantiere SubHttpExceptions i stedet for HttpException ;-)
Avatar billede brooks Nybegynder
09. april 2003 - 12:33 #8
Det er en glimrende mulighed, desværre er det ikke altid mig selv, der står for at smide de exceptions, ofte er det jo ASP.NET selv.

Men jeg laver bare en custom serializer, ala ovenstående. Måske bliver jeg rigtig doven og bare gemmmer exception.ToString()...
Avatar billede burningice Nybegynder
09. april 2003 - 12:41 #9
z42cool>> så han da sørge for at fange alle HttpExceptions og sørge for at kaste sin egen istedet ;)

ala

try {

} catch (HttpException e) {
    throw new MyHttpException(e);
}
Avatar billede z42cool Nybegynder
09. april 2003 - 12:53 #10
Men det bliver HttpException jo ikke serializable af, dvs. det bliver nødvendigt at:

try
{
}
catch (HttpException e)
{
  //Vi kan ikke bruge innerException funktionalitet da vi jo ikke
  //kan serialisere HttpException
  SubHttpException subE = new SubHttpException(e.propertyEt, e.propertyTo);
}

Det kan måske godt lade sig gøre, men det bryder med den "standard" der er for exceptions, nemlig at ved genkast skal den nye exception referere den oprindelige exception gennem innerException. Alt i alt må den rigtige løsning være custom serialization.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester