[C#] Error na Response.Redirect

Door Luuk1983 op maandag 9 november 2009 12:24 - Reacties (12)
Categorie: Programmeren, Views: 3.502

Soms kan je tijdens het programmeren van die problemen tegen waarvan je denkt: Wtf is DIT nou weer?!?!?!?! Hele eenvoudige commando's die je heel regelmatig gebruikt geven een fout, terwijl je er eigenlijk heel weinig fout aan kan doen. Zo kwam ik laatst een fout tegen bij het gebruik van Response.Redirect().

Als er 1 functie is die ik vaak gebruik dan is het Response.Redirect(). Wat het doet mag duidelijk wezen: je Redirect van de huidige pagina naar een nieuwe pagina, bijvoorbeeld

C#:
1
Response.Redirect ("pagina.aspx");


Hoeveel kan je hier fout aan doen, right? Maar toch kreeg is een error, namelijk een 'thread aborted' exception.

Allereerst even de situatie in het kort. We hebben een object aangemaakt waarmee je met de volgende code een melding of een error kan toevoegen:

C#:
1
2
Website.AddError("Het ging fout");
Website.AddInfo("Het opslaan is met succes voltooid");


Deze meldingen worden als collectie in een sessie gestopt en bij de volgende Request (dus na een reload) worden deze sessies uitgelezen, verwijderd uit de sessie en weergegeven op de website. Dit zorgt voor een consistente manier van meldingen geven.
Ik heb de volgende code (uiteraard heel erg versimpeld) gemaakt:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
try
{
//Do wat dingen hier
DoeWat();

//Dingen zijn met succes afgerond
Website.AddInfo("Alle dingen zijn met succes afgerond");
Response.Redirect("TerugNaarMenu.aspx");
}
catch (Exception ex)
{
Website.AddError("Er is iets fout gegaan: "+ex.Message);
}


Als ik bovenstaande code uitvoerde werd 'DoeWat()' met succes afgerond, werd op het scherm de melding 'Alle dingen zijn met succes afgerond' weergegeven en er werd geredirect naar TerugNaarMenu.aspx. Echter, er kwam ook de melding te staan 'Er is iets fout gegaan: Thread abort exception".

Wat blijkt nu: Response.Redirect veroorzaakt STANDAARD een ThreadAbortException en blijkbaar wordt die gebruikt om de redirect mogelijk te maken. Deze exception wordt door het framework afgevangen en zal dus nooit een servererror op je scherm geven. Normaal merk je daar niks van, maar omdat in bovenstaande code de errors in een session gestopt worden komt deze later toch weer naar boven. In zekere zin was dit dus niet 'fout', maar standaard gedrag waar je normaal gesproken niets van ziet.

Er zijn uiteraard 2 manieren op dit op te lossen:
- De Response.Redirect uit de try, catch loop halen.
- De ThreadAbortException afvangen.

Ik heb voor dat laatste gekozen:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try
{
//Do wat dingen hier
DoeWat();

//Dingen zijn met succes afgerond
Website.AddInfo("Alle dingen zijn met succes afgerond");
Response.Redirect("TerugNaarMenu.aspx");
}
catch (ThreadAbortException ex)
{ }
catch (Exception ex)
{
Website.AddError("Er is iets fout gegaan: "+ex.Message);
}

Volgende: Brutes: zinloos verslavend spel 11-'09 Brutes: zinloos verslavend spel
Volgende: Microsoft: OEM illegaal voor consument 10-'09 Microsoft: OEM illegaal voor consument

Reacties


Door Tweakers user IJsbeer, maandag 9 november 2009 12:32

De redirect heeft ook een overload (string URL, bool endResponse). Als je de tweede parameter false meegeeft maakt ie eerst de huidige request af en is het probleem dus ook opgelost.
Het mooiste vind ik het buiten de try...catch. Maar dat is niet alitjd mogelijk.

Door Tweakers user Luuk1983, maandag 9 november 2009 12:34

@Ijsbeer,
Inderdaad, dat ben ik erbij vergeten te melden. Dat heeft echter niet echt mijn voorkeur, performance-wise. Ik denk dat je het in de prakijk niet gaat merken, maar om (in feite nutteloos) de response af te gaan maken vind ik een beetje jammer.

Maar je hebt gelijk dat het zeker een alternatief is.

Door Tweakers user Snake, maandag 9 november 2009 12:43

NOOIT Exception catchen. Nasty. Zeer nasty!

Door Tweakers user boe2, maandag 9 november 2009 13:03

Er zijn situaties waar het aanvaardbaar is om Exceptions weg te stoppen. Dit is er eentje van :)

Door Tweakers user SolvingStorm, maandag 9 november 2009 13:03

Volgens mij is t nasty om exceptions niet te catchen. Of werkt het in een web omgeving anders als in windows omgeving?

Door Tweakers user neothor, maandag 9 november 2009 13:11

@Snake waarom zou het nasty zijn om een exception te catchen. Wat nasty is in mijn ogen is het catchen van een exception en er niets mee te doen.

Uitzonderingen daar gelaten ;)

[Reactie gewijzigd op maandag 9 november 2009 13:12]


Door Tweakers user Little Penguin, maandag 9 november 2009 13:32

NOOIT Exception catchen. Nasty. Zeer nasty!
Aan de andere kant is het gebruik van een exception on een redirect af te handelen nu ook niet direct het schoolvoorbeeld van goed programmeren.

Nog even en er wordt een exception gebruikt om een if/then/else constructie af te handelen.

De programmeur dat deze code mag wat mij betreft dan ook terug naar de programmeer-kleuterklas...

Door Tweakers user Luuk1983, maandag 9 november 2009 13:41

@Snake,

Ik vang (eventueel) Exceptions alleen af op form niveau, om bijvoorbeeld een goede foutmelding te kunnen geven. In classes en assembly's vind ik dat je per definitie geen Exceptions mag afvangen, omdat je ze op die manier verbergt voor de gebruiker van die assembly of class.

@SolvingStorm

Zoals ik zei op form niveau moet je ze uiteindelijk wel afvangen en een (mooie) foutmelding geven en eventueel naar een log schrijven of een mail naar de beheerder sturen. Op een 'hoger' niveau dus absoluut niet.

[Reactie gewijzigd op maandag 9 november 2009 13:46]


Door Tweakers user SolvingStorm, maandag 9 november 2009 14:22

Dat ben ik met je eens, ik was het niet eens met de stelling om NOOIT een exception te vangen.

Door Tweakers user Roobin79, maandag 9 november 2009 16:15

Ik dacht ook even, wat raar om te zeggen dat het nasty is om exceptions te catchen. Maar volgens mij bedoelt Snake dat het nasty is om Exception te catchen. Klinkt bijna hetzelfde, maar is heel wat anders.

Als ik Snake goed begrijp, dan ken ik zijn standpunt. Catch alleen bekende exceptions, zoals bijvoorbeeld een SqlException. "Do Not Catch General Exception Types" is een regel uit fxcop.

Door Tweakers user pasz, maandag 9 november 2009 17:19

Waarom moet je perse een redirect gebruiken ? Ik gebruik dat bijna nooit in mijn webapplicaties :S

Door Tweakers user TeeDee, maandag 9 november 2009 22:23

@pasz: wat heb jij dan als alternatief? In een OnClick redirecten naar bijv. een externe site, andere pagina etc. kan imo niet anders dan met een Redirect.

Reactie formulier
(verplicht)
(verplicht, maar wordt niet getoond)
(optioneel)