2011-06-18 6 views
0

Je rencontre un problème avec la conversion au code Excel que je trouve. Je travaille sur un projet de site Web dans .NET 4.0, et j'ai créé une classe pour ce qui effectue les opérations suivantes (basé sur http://mattberseth.com/blog/2007/04/export_gridview_to_excel_1.html):Exporter vers Excel - ThreadAbortException

HttpContext.Current.Response.Clear(); 
HttpContext.Current.Response.AddHeader("content-disposition", 
string.Format("attachment; filename={0}", fileName)); HttpContext.Current.Response.ContentType = "application/ms-excel"; using (StringWriter sw = new StringWriter()) { 
    using (HtmlTextWriter htw = new HtmlTextWriter(sw)) { 
    //Create a table to contain the grid 
    //Add header row 
    //Add each data row 
    //Add Footer row 
    //Render the table into the htmlwriter 
    // render the htmlwriter into the response 
    HttpContext.Current.Response.Write(sw.ToString()); 
    HttpContext.Current.Response.End(); 
    } 
} 

J'appelle cette classe d'un UserControl qui contient un bouton est ajouté à un GridView affiché sur la page. Cela fonctionne comme prévu - cliquez sur le bouton, vous êtes présenté avec une option de téléchargement pour ouvrir ou enregistrer la feuille de calcul Excel contenant les données de GridView. Cependant, lorsque j'appelle ceci à partir d'un lien de bouton dans un autre GridView, je voudrais construire une grille dynamique pour contenir les données et les exporter. Lorsque je fais cela, je reçois une exception ThreadAbortException de l'appel Response.End dans la classe.

Question 1: Pourquoi ne reçois-je pas ThreadAbortException lorsque j'appelle le même code depuis un usercontrol? Les contrôles usuels ont-ils leur propre fil conducteur ou un autre contexte?

La recherche sur l'erreur que je reçois lorsque cette ThreadAbortException se produit m'a conduit à tenter de le remplacer par ApplicationInstance.CompleteRequest(). Quand je fais cela, je n'obtiens plus l'exception ThreadAbortException, mais cela casse la commande usercontrol précédente - au lieu de la feuille de calcul Excel contenant les données de la grille, elle contient le code HTML de la page contenant, et en tout cas il est assez facile de supprimer cette erreur avec une capture vide. Cependant, il ne fixe pas l'appel direct avec le GridView généré dynamiquement, ce code rend une erreur javascript: "Le message reçu du serveur n'a pas pu être analysé." Je voudrais bien comprendre ce qui se passe exactement ici, mais je suis sur le point d'avoir besoin de résultats, indépendamment de la compréhension. Toutes les autres approches que j'ai essayées (datagrid au lieu de GridView, etc) rencontrent les mêmes problèmes, et sont essentiellement les mêmes quand il s'agit de "prendre en charge" la réponse actuelle et en utilisant stringwriter et htmlwriter pour rendre les données dans une réponse avec excel contentType. Et puisque cela fonctionne manifestement dans le cadre d'un usercontrol, je suis à ma fin de l'esprit pour expliquer pourquoi il ne fonctionnera pas lorsqu'il est appelé directement ...

+0

duplication possible de [Pourquoi mon application asp.net lance-t-elle ThreadAbortException?] (Http://stackoverflow.com/questions/12476/why-is-my-asp-net-application-throwing-threadabortexception) –

+0

Je crois qu'il s'agit d'un doublon - il s'agit d'un cas très spécifique traitant de deux scénarios - un où il arrive pour un appel à response.end, et l'autre il doesnt –

Répondre

0

Le problème était en fait complètement indépendant de l'exportation Excel. L'erreur "... impossible à analyser" était la clé. A partir de ces liens que je suis la clé, à savoir que les événements de la grille provoquent seulement un événement postback partiel:

http://forums.asp.net/t/1392827.aspx

http://forums.aspfree.com/net-development-11/gridview-footer-template-button-in-updatepanel-not-posting-back-236087.html

Ceci explique la ThreadAbortException et le « ... ne pouvait pas être analysé » erreur.Ajoutant cela au OnPreRender du ImageButton a été la solution:

protected void addTrigger_PreRender(object sender, EventArgs e) 
{ 
    if (sender is ImageButton) 
    { 
     ImageButton imgBtn = (ImageButton)sender; 
     ScriptManager ScriptMgr = (ScriptManager)this.FindControl("ScriptManager1"); 
     ScriptMgr.RegisterPostBackControl(ImgBtn); 
    } 
} 
0

Essayez plutôt: HttpApplication.CompleteRequest() selon: http://www.c6software.com/codesolutions/dotnet/threadabortexception.aspx

Ils discutent du html supplémentaire étant flished

+0

Passer à CompleteRequest évite l'erreur, comme je l'ai déclaré dans le question, mais il ne répond pas à l'erreur javascript "Le message reçu du serveur n'a pas pu être analysé." J'ai ajouté les remplacements mentionnés de votre lien, sans effet. – Jarrod

+0

Regardez les données qui reviennent dans Fiddler (www.fiddler2.com) - quelque chose écrit peut-être dans le flux de réponse auquel vous ne vous attendez pas et vous devrez peut-être mettre en tampon la sortie et response.clear, mais essayez le fiddler. –

+0

Adam, je me souviendrai de l'utiliser la prochaine fois que je rencontrerai un problème comme celui-ci. merci pour la suggestion et la contribution. J'ai posté la solution, comme j'ai trouvé la racine du problème. Merci encore. – Jarrod

0

utilisent ce

Response.Clear() 
    Response.AddHeader("content-disposition", atchment;filename=fm_specification.xls") 
    Response.Charset = "" 
    Response.Cache.SetCacheability(HttpCacheability.NoCache) 
    Response.ContentType = "application/vnd.xls" 
    Dim stringWrite As System.IO.StringWriter = New System.IO.StringWriter 
    Dim htmlwrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite) 
    GridView1.RenderControl(htmlwrite) 
    Response.Write(stringWrite.ToString) 
    Response.End() 

au lieu de GridView1 vous pouvez utiliser div

      dont forget to add this on your page 

Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control) 
End Sub 
+0

À l'exception de Response.Charset = "" et Response.Cache.SetCacheablility (HttpCacheability.NoCache), cela est identique à ce que j'ai. Il n'est peut-être pas surprenant que l'ajout de ces lignes n'ait eu aucun effet. Je reçois l'exception ThreadAbortException à moins que je ne le supprime et, dans les deux cas, j'obtiens l'erreur javascript "Le message reçu du serveur n'a pas pu être analysé." J'ai vérifié VerifyRenderingInServerForm dans la page. – Jarrod

+0

avez-vous ajouté ValidateRequest = "false" en haut de votre page source aspx où la classe de page est définie? – Vikky

+0

non, je n'ai pas. Je ne vois pas où vous avez mentionné cela. J'ai pu trouver l'erreur et j'ai posté ma réponse. Merci de votre contribution sur cette question. Très appréciée. – Jarrod

0

L'événement sur lequel l'exportation vers Excel code est appelé, doit faire un postback complet. le problème est dû au fait qu'il ne fait qu'une publication partielle.

J'ai eu la même erreur et il a été résolu lorsque j'ai fait une publication complète.

Espérons que cela aide quelqu'un.