web-dev-qa-db-fra.com

HttpContext lève HttpException

J'ai écrit un gestionnaire http personnalisé. J'ai fait cela en écrivant une classe qui implémente IHttphandler.

Dans cette classe, j'ai un code comme celui-ci,

context.Response.Clear();
context.Response.ClearHeaders();
context.Response.AddHeader("Content-Disposition", "attachment;filename=" + attachmentFileName);
context.Response.AddHeader("Content-Length", new FileInfo(downloadFile).Length.ToString());
context.Response.ContentType = GetMimeType(attachmentFileName);
context.Response.TransmitFile(downloadFile);
context.Response.Flush();
context.Response.Close();

Parfois, je reçois une erreur comme celle-ci,

Exception HttpException The remote Host closed the connection The error code is 0x800703E3

Ou ca,

Exception HttpException The remote Host closed the connection The error code is 0x80070040

Dans les deux cas, la trace de la pile est la suivante:

at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
at System.Web.HttpResponse.Flush(Boolean finalFlush)
at System.Web.HttpResponse.Flush()

Cela se produit en production, et si je regarde en arrière au cours des derniers jours, 23 erreurs se sont produites et, au total, le code ci-dessus a été appelé 497 fois.

Je soupçonne que cet échec est lié au fait que l'utilisateur clique sur le lien pour lancer le code ci-dessus plusieurs fois (ce qui leur donnera plusieurs boîtes de dialogue de téléchargement), puis annule certaines d'entre elles. Cela dit, si c’était quelque chose comme cela, je me serais attendu à ce que la connexion se ferme de façon élégante des deux côtés.

Comment puis-je prouver la cause exacte de cette erreur? J'ai essayé d'activer le traçage .NET comme ceci Pourquoi le suivi des écouteurs n'enregistre-t-il pas le trafic des gestionnaires personnalisés? mais je ne pouvais pas le faire fonctionner.

Ce que j’ai trouvé, c’est que j’ai activé le traçage IIS pour consigner les demandes ayant échoué. L'échec s'est à nouveau produit et RIEN ne figurait dans ce journal.

Tout autre traçage que je peux activer par exemple?

La chose suivante que j'ai essayée était la suivante:

if (context.Response.IsClientConnected)
{
    context.Response.Flush();
    context.Response.Close();
}
else
{
    LogMessage("Client has disconnected before flush was called", Severity.Information);
}

Mais cela n'a fait aucune différence. La raison en est que le client s'est déconnecté pendant le téléchargement, pas avant l'appel de flush.

20
peter

Sortez les appels Flush() et Close(). Vous n'avez vraiment pas besoin d'eux. Une fois que votre gestionnaire est terminé, il se ferme et ASP.NET gère la fermeture de la demande.

De plus, Flush() devrait être utilisé lorsque vous transmettez du contenu au client (ajout de parties au bloc de réponses par blocs). Vous n'avez pas besoin de l'utiliser avec TransmitFile().

14
Samuel Neff

J'étais dans des problèmes similaires, cet article explique pourquoi Response.End () doit être évité et suggère d'utiliser la méthode CompleteRequest (). La documentation MSDN a également été mise à jour avec ces informations. J'espère que ça aidera quelqu'un.

http://blogs.msdn.com/b/aspnetue/archive/2010/05/25/response-end-response-close-and-how-customer-feedback-helps-us-improve-msdn-documentation. aspx

8
DotNetUser

Utilisez Response.End() au lieu de Response.Flush()

Voici à quoi ressemble le code source de Response.End():

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}
4
smartcaveman

Quel framework .NET utilisez-vous? Ce fil de discussion ici décrit un problème similaire lié à la déconnexion du client, lié à l'utilisation de IIS7 avec .NET2.0. Ce problème a été résolu dans .NET Framework 3.5

Le code d'erreur réel correspond à 

0x800703E3 "The I/O operation has been aborted because of either a thread exit or an application request."
2
Dan

essayez de configurer le fichier de taille maximale de la configuration Web en un fichier plus volumineux.

Vous pouvez définir le maxRequestLength (en ko)

essayez de ne pas reclycle les pools d'applications sur IIS et souvent aussi.

1
jack.the.ripper

Pour plus de détails sur cette exception, visitez http://support.Microsoft.com/kb/977453

1
Sooraj

J'ai parfois l'erreur:

Exception message: An error occurred while communicating with the remote Host. The error code is 0x80070057.

Est aléatoire dans la production. Ce n'est pas reproduire en développement ou en assurance qualité.

Je vais appliquer cette solution: Response.IsClientConnected J'espère que cela corrigera l'erreur.

La source:

https://stackoverflow.com/a/11441375/1536197

0