Weblog @ rebex.cz

Weblogy na webu Rebexu
Welcome to Weblog @ rebex.cz Sign in | Help
in Search

Weblog @ Rebex.cz :: Honza Šotola

nepravidelné poznámky .NET vývojáře

Ukončení ASPX stránky pomocí Response.End není ideální

Možná objevuji Ameriku, ale přinejmenším vývojářům v Rebexu doporučuji tento článek přečíst a začít se jím řídit.

Response.End jsem dlouho nepotřeboval používat (kromě ukončování stránek při ladění) a setkávám se s ním teprve v poslední době, kdy jsme si navykli exportovat data z ASPX stránek dle následujícího scénáře:
(scénář je převzat přímo z jendoho dema k DevExpress PivotGridu)

MemoryStream vystup = ZiskejVystupniData();
Response.Clear();
//...nastavení Response HTTP headeru...
Response.BinaryWrite(vystup.GetBuffer);
Response.End();

Pokud na dané stránce explicitně odchytáváte výjimky, zjistíte, že hází ThreadAbortException
(pokud ale výjimku neodchytáváte, stránka nespadne a v vše funguje bez viditelných problémů).

Článek v MSDN bázi znalostí doporučuje namísto Response.End použít
HttpContext.Current.ApplicationInstance.CompleteRequest.
To obvykle zafunguje, dosud s tím nemám žádné negativní zkušenosti a doporučuji tento způsob preferovat.

UPDATE: uprostřed jenoho diskusního příspěvku jsem se dočetl (a v praxi si ověřil), že i CompleteRequest má svou nevýhodu: narozdíl od Response.End či Response.Close nezajistí, aby se po zavolání CompleteRequest už NIC nezapsalo do Response.Output streamu. K zápisu může dojít následným voláním Response.Write ale do streamu se dostane i text vyrenderovaný z .ASPX souboru. Naštěstí se tento výstup dá celkem dobře potlačit pomocí override metod RaisePostBackEvent a Render - blíže viz pěkném shrnujícím článku na toto téma.

Interní poznámka pro vývojáře v Rebexu:
Ukončování stránek pomocí HttpContext.Current.ApplicationInstance.CompleteRequest bohužel nezafunguje v starých projektech, kde se používá UcPage.
V takových situacích doporučuji odchytávat při volání Response.Endu výjimku ThreadAbortException a zahazovat ji.

Published 20. listopadu 2009 12:36 by honzas
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Robert Haken [MVP ASP.NET] said:

ThreadAbortException je tam by-design a je to prostě takto funkčně navržena a celé je to na té výjimce založeno, není to nic zvláštního. Viz např. dokumentace http://msdn.microsoft.com/en-us/library/system.web.httpresponse.end(VS.80).aspx. Dá se k tomu někde najít i vysvětlení konceptu.

května 21, 2010 0:47
 

honzas said:

Jasně.

Souhlasím s tím, že ThreadAbortException tam patří. Jen nepovažuji za správné, aby se vyhazovala (a v našem případě i logovala) při každém (zcela regulérním) exportu souboru z ASPX stránky. Právě proto doporučuji buď použít CompleteRequest a nebo ji chytat a nemaskovaně zahazovat (děje se v legacy Rebex aplikacích, které používají jednu naši starou knihovnu).

Jinak celkem pěkné shrnutí rozdílů mezi Response.End a CompleteRequest je v následujícím článku: http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation.aspx

září 16, 2010 15:43

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Personal Edition), by Telligent Systems