none
Response.End() wirft Fehler RRS feed

  • Frage

  • Hallo,

    probiere die ganze Zeit dynamische Dateien dem admin zum downloaden anzubieten.
    Dazu verwende ich den folgenden Code in ein Webservice-Datei (Handler.ashx).

    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.ClearHeaders();
    HttpContext.Current.Response.ClearContent();
    HttpContext.Current.Response.ContentType = "application/pdf";
    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + fi.Name);
    HttpContext.Current.Response.AddHeader("Content-Length", fi.Length.ToString());
    HttpContext.Current.Response.Flush();
    HttpContext.Current.Response.TransmitFile(fi.FullName);
    HttpContext.Current.Response.End();
    //HttpContext.Current.ApplicationInstance.CompleteRequest();
    Jedesmal wenn in der Zeile Response.End(), wird der Fehler ausgegeben
    Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack
    Habe versucht auch die Datei mit BinaryWrite und etliche anderen alternativen ,downzuladen jedoch lief das auch schief.
    Mit
    HttpContext.Current.ApplicationInstance.CompleteRequest();
    wird zwar kein Fehler ausgegeben jedoch wird die Datei auch nicht zum Download angeboten.

    Was mache ich falsch.
    Ich wäre für jede Antwort sehr sehr dankbar.

    Lg
    WaZZ

    Montag, 3. Oktober 2016 15:11

Antworten

  • Hallo WaZZ,

    mir ist der Sinn des Umwegs über Ajax->Webservice->Generischer Handler nicht ganz klar.

    Du kannst, falls du beispielsweise ein Button-Click-Event auswertest (-> Download) den Handler (ashx) direkt aufrufen:

    protected void Button1_Click(object sender, EventArgs e) {
      Response.Redirect("~/getpdf.ashx", false);
    }

    Im Handler ist die Methode bei mir wie folgt:

    public void ProcessRequest(HttpContext context) {
    	string fileName = String.Empty;
    	byte[] pdfData;
    	HttpResponse rsp = null;
    	try {
    		fileName = context.Server.MapPath("~/app_data/iis.pdf");
    		pdfData = System.IO.File.ReadAllBytes(fileName);
    		rsp = HttpContext.Current.Response;
    		//-------------------------------------------------
    		rsp.ClearHeaders();
    		rsp.Clear();
    		rsp.ClearContent();
    		rsp.ContentType = "Application/pdf";
    		rsp.Buffer = false;
    		rsp.AddHeader("content-disposition", "attachment; filename=iis.pdf");
    		rsp.OutputStream.Write(pdfData, 0, pdfData.Length);
    		rsp.Flush();
    		rsp.SuppressContent = true;
    	} catch ( Exception ex ) {
    		string msg = ex.ToString();
    	}
    }

    Nebenbei bemerkt, würde das auch funktionieren, wenn du den Body der Methode aus dem Handler sinngemäß im Button-Click-Handler direkt platzieren würdest (context nur zu Context ändern), solange du in den im Seiten-Zyklus folgenden Events (z.B. Page_LoadComplete, ...) keine weiteren Ausgaben produzierst. Dann könntest du sogar auf den Handler verzichten.

    Gruß, K.

    Dienstag, 4. Oktober 2016 15:02
  • Hi,

    warum willst Du überhaupt für ein abruptes Ende bzw. die Umgehung aller weiteren Events und den Sprung zu EndRequest sorgen?

    Setz doch mal einen Breakpoint und schau, ob fi.FullName überhaupt auf eine existierende Datei zeigt.

    Falls ja, füg mal:

    HttpContext.Current.Response.Flush();

    hinter TransmitFile und nicht davor ein.

    Ein Handler (ASHX) hat zudem über die ProcessRequest Methode seinen eigenen Context. Der ist zwar eigentlich identisch mit HttpContext.Current aber ich würde es dennoch mal damit probieren, den Handler Context zu verwenden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community



    Montag, 3. Oktober 2016 16:59
    Moderator
  • Hi,

    zum einen ist deine Überlegung zwar nachvollziehbar aber leider erreichst Du noch nicht mal im Ansatz etwas mehr Sicherheit mit deiner Methode zur Datenübertragung.

    Was zwischen Client und Server ausgetauscht wird, wird ausgetauscht. Wenn auf dem Client irgendwas vorhanden ist, was den Datenverkehr belauschen kann, hilft es dir nicht, den Datenverkehr auf eine andere Art und Weise vorzunehmen. Der Client ist befallen und damit zu entsorgen (zumindest das gesamte OS, sprich: Komplette Neuinstallation, es sei denn, der Schadcode ist in der Hardware, dann ggfs. auch mehr^^)

    Zudem arbeitest Du nicht mit einem Webservice, sondern mit einem Handler. D.h. dieser wird so oder so über einen URL aufgerufen. Ob das nun im Browser sichtbar ist oder nicht, spielt für einen Sniffer keine Rolle. Der kann das trotzdem lesen.

    Fazit: Das, was Du machen willst, geht so überhaupt nicht, da Javascript mit dem, was vom Handler geliefert wird, auch rein gar nichts anfangen könnte.

    Für Alternativen schau mal hier:

      http://stackoverflow.com/questions/4545311/download-a-file-by-jquery-ajax


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 4. Oktober 2016 09:55
    Moderator

Alle Antworten

  • Hi,

    warum willst Du überhaupt für ein abruptes Ende bzw. die Umgehung aller weiteren Events und den Sprung zu EndRequest sorgen?

    Setz doch mal einen Breakpoint und schau, ob fi.FullName überhaupt auf eine existierende Datei zeigt.

    Falls ja, füg mal:

    HttpContext.Current.Response.Flush();

    hinter TransmitFile und nicht davor ein.

    Ein Handler (ASHX) hat zudem über die ProcessRequest Methode seinen eigenen Context. Der ist zwar eigentlich identisch mit HttpContext.Current aber ich würde es dennoch mal damit probieren, den Handler Context zu verwenden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community



    Montag, 3. Oktober 2016 16:59
    Moderator
  • Hallo und danke für deine Antwort.

    Also, das fi.FullName verweist auf eine existierende Datei.
    Mit dem context vom Handler verhält sichs gleich.
    Es passiert nichts, keine Datei zum downloaden ect.
    Das einzige was mir in der JS Methode auffält ist, das die PDF Datei zumindest bis zur JS Methode zurückkommt.

    %PDF-1.3
    1 0 obj
    [/PDF /Text /ImageB /ImageC /ImageI]
    endobj
    6 0 obj
    << /Length 1169 /Filter /FlateDecode >> stream
    X	...
    Entweder bin ich zu blöd für die paar Zeilen oder ich weiss es nicht.


    Ich könnte mir auch den Pfad zurück geben und die Datei mittels
    window.open
    oder
    window.location.href
    aufrufen, jedoch ist mir das zu unsicher.

    Danke und Lg
    WaZZ
    Dienstag, 4. Oktober 2016 04:24
  • Hi,

    welche JS Methode? Und was sollte an window.location.href unsicher sein?

    Letztendlich solltest Du den Client per window.location.href, <a href="..." ...> oder ählichem dazu bringen, den gewünschten URL aufzurufen, also deinen Handler mit Übergabe der notwendigen Parameter.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 4. Oktober 2016 07:07
    Moderator
  • Falls auf den Client ein Sniffer, Virus ect. vorhanden sein sollte, könnte dieser bsp. die aufgerufenen URLs auslesen und so den Speicherort der Daien auf dem Server herausfinden.
    Auf der Seite passieren keine Postbacks, daher wenn die Seite einmal aufgerufen wird ändert sich die Url auch nicht mehr.

    Ich möchte nicht die Datei über die URL als Download anbieten sondern eher alles im Webservice vorbereiten und auch dort zum download anbieten.

    Die JS-Methode dazu ist Simple
    $.ajax({
        type: "GET",
        data: param,
        url: "/Webservice.ashx",
        contentType: "application/json; charset=utf-8",
        secureuri: true,
        success: function (e) {
            glb_obj = e; // Object (kann auch URL sein) wird ggf. hier übergeben
        },
        error: function (e) {
            ...
        }
    });

    Und in der ashx Datei möchte ich einfach mit
    FileInfo fi = new FileInfo(HttpContext.Current.Session["pdf"].ToString());
    context.Response.Clear();
    context.Response.ClearHeaders();
    context.Response.ClearContent();
    context.Response.ContentType = "application/pdf";
    context.Response.AddHeader("Content-Disposition", "attachment; filename=" + fi.Name);
    context.Response.AddHeader("Content-Length", fi.Length.ToString());
    context.Response.TransmitFile(fi.FullName);
    context.Response.Flush();
    context.ApplicationInstance.CompleteRequest();
    //context.Response.End();
    den Download anbieten.


    Besten Dank und Lg
    WaZZ









    • Bearbeitet WaZZkeSS Dienstag, 4. Oktober 2016 09:46
    Dienstag, 4. Oktober 2016 09:46
  • Hi,

    zum einen ist deine Überlegung zwar nachvollziehbar aber leider erreichst Du noch nicht mal im Ansatz etwas mehr Sicherheit mit deiner Methode zur Datenübertragung.

    Was zwischen Client und Server ausgetauscht wird, wird ausgetauscht. Wenn auf dem Client irgendwas vorhanden ist, was den Datenverkehr belauschen kann, hilft es dir nicht, den Datenverkehr auf eine andere Art und Weise vorzunehmen. Der Client ist befallen und damit zu entsorgen (zumindest das gesamte OS, sprich: Komplette Neuinstallation, es sei denn, der Schadcode ist in der Hardware, dann ggfs. auch mehr^^)

    Zudem arbeitest Du nicht mit einem Webservice, sondern mit einem Handler. D.h. dieser wird so oder so über einen URL aufgerufen. Ob das nun im Browser sichtbar ist oder nicht, spielt für einen Sniffer keine Rolle. Der kann das trotzdem lesen.

    Fazit: Das, was Du machen willst, geht so überhaupt nicht, da Javascript mit dem, was vom Handler geliefert wird, auch rein gar nichts anfangen könnte.

    Für Alternativen schau mal hier:

      http://stackoverflow.com/questions/4545311/download-a-file-by-jquery-ajax


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 4. Oktober 2016 09:55
    Moderator
  • Hallo WaZZ,

    mir ist der Sinn des Umwegs über Ajax->Webservice->Generischer Handler nicht ganz klar.

    Du kannst, falls du beispielsweise ein Button-Click-Event auswertest (-> Download) den Handler (ashx) direkt aufrufen:

    protected void Button1_Click(object sender, EventArgs e) {
      Response.Redirect("~/getpdf.ashx", false);
    }

    Im Handler ist die Methode bei mir wie folgt:

    public void ProcessRequest(HttpContext context) {
    	string fileName = String.Empty;
    	byte[] pdfData;
    	HttpResponse rsp = null;
    	try {
    		fileName = context.Server.MapPath("~/app_data/iis.pdf");
    		pdfData = System.IO.File.ReadAllBytes(fileName);
    		rsp = HttpContext.Current.Response;
    		//-------------------------------------------------
    		rsp.ClearHeaders();
    		rsp.Clear();
    		rsp.ClearContent();
    		rsp.ContentType = "Application/pdf";
    		rsp.Buffer = false;
    		rsp.AddHeader("content-disposition", "attachment; filename=iis.pdf");
    		rsp.OutputStream.Write(pdfData, 0, pdfData.Length);
    		rsp.Flush();
    		rsp.SuppressContent = true;
    	} catch ( Exception ex ) {
    		string msg = ex.ToString();
    	}
    }

    Nebenbei bemerkt, würde das auch funktionieren, wenn du den Body der Methode aus dem Handler sinngemäß im Button-Click-Handler direkt platzieren würdest (context nur zu Context ändern), solange du in den im Seiten-Zyklus folgenden Events (z.B. Page_LoadComplete, ...) keine weiteren Ausgaben produzierst. Dann könntest du sogar auf den Handler verzichten.

    Gruß, K.

    Dienstag, 4. Oktober 2016 15:02