Laden...

UpdatePanel funktioniert einfach nicht!

Erstellt von math55 vor 13 Jahren Letzter Beitrag vor 13 Jahren 6.166 Views
math55 Themenstarter:in
314 Beiträge seit 2007
vor 13 Jahren
UpdatePanel funktioniert einfach nicht!

Hallo, ich habe auf meiner Seite einen ImageButton, welcher Dateien auf dem Server erzeugt. Dazu gehört eine DropDownList, welche die Dateien anzeigt. Funktioniert auch alles ganz gut. Jetzt möchte ich aber, dass die DropDownList die gerade erzeugte Datei ebenfalls anzeigt.

Es scheint nicht zu reichen, DataBind aufzurufen, die neue Datei ist nicht enthalten, erst nachdem ich erneut auf die Seite gehe. Ich habe mich also an einem UpdatePanel versucht:


...
 <asp:ImageButton ID="IB_ExportInvoices" runat="server" ImageUrl="themes/resources/images/buttons/CreateDocuments.gif"
                    ToolTip="SAP FSCS Datei exportieren" OnClick="IB_ExportInvoices_Click"></asp:ImageButton>
....
<asp:UpdatePanel ID="UP_ExportInvoices" runat="server"  UpdateMode="Conditional">
                    <ContentTemplate>
                        <asp:DropDownList ID="DDL_ExportFileDownLoad" runat="server" AutoPostBack="true"
                            OnSelectedIndexChanged="DDL_ExportFileDownLoad_SelectedIndexChanged">
                        </asp:DropDownList>
                    </ContentTemplate>
                    <Triggers>
                        <asp:AsyncPostBackTrigger ControlID="IB_ExportInvoices" EventName="Click"/>
                    </Triggers>
                </asp:UpdatePanel>

Der IB_ExportInvoices button ist nicht im UpdatePanel enthalten. Funktioniert leider so nicht (Fehlermeldung) ... was mache ich falsch?

Die Fehlermeldung ist:

Laufzeitfehler in Microsoft JScript: Sys.WebForms.PageRequestManagerParserErrorException: Die vom Server empfangene Nachricht konnte nicht analysiert werden. Häufige Ursachen für diesen Fehler sind: Änderung der Antwort durch Aufrufe von Response.Write(), Antwortfilter, HttpModules oder aktivierte Serverablaufverfolgung.
Details: Fehler beim Analysieren in der Nähe von "12345678901200908182".

Danke 😃

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

am geposteten Teil des Codes liegt es jedenfalls nicht. Der funktioniert, und ohne UpdatePanel funktioniert es auch (hatte zum Testen mir einfach mal 'ne statische List<string> gebaut und per Click auf den ImageButton jeweils einen Eintrag hinzugefügt, danach neu gebunden).

Ich nehme an Du bindest die Daten zu früh (DataBind-Aufruf schon im Page_Load??), wenn Dein neuer Eintrag nicht erscheint.

Warum das mit dem UpdatePanel bei Dir einen Fehler gibt, kann ich nicht nachvollziehen (ich bekomme keinen).

Ursachen für diesen Fehler sind: Änderung der Antwort durch Aufrufe von Response.Write(), Antwortfilter, HttpModules oder aktivierte Serverablaufverfolgung.

Rufst Du irgendwo Response.Write() auf in Deinem Code? Wenn nicht, vermute ich ein Konfigurationsproblem.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

691 Beiträge seit 2007
vor 13 Jahren

Hast du auf deiner Seite einen ScriptManager bzw auf der MasterPage einen ScriptManager und auf der Contentseite einen ScriptManagerProxy eingebaut?

mit freundlichen Grüßen,
Tomot

Projekte: www.gesellschaftsspieler-gesucht.de

math55 Themenstarter:in
314 Beiträge seit 2007
vor 13 Jahren

Hi, ich binde das im Page_Load, richtig. Wo wäre es denn besser?

Grüße

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

richtig wäre im IB_ExportInvoices_Click nachdem die Datei schon erzeugt wurde, oder im Page_PreRender, da es auch erst nach dem Clickereignis aufgerufen wird und somit die neuen Daten bereits vorhenden sind.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

math55 Themenstarter:in
314 Beiträge seit 2007
vor 13 Jahren

Hi, ich denke, das Problem ist, dass ich zudem auch noch die gerade erzeugte Datei zum Download anbiete. Das sind warscheinlich dann 2 Sachen für den Server und das bringt alles durcheinander. Bisher war der Ablauf so:

1. Datei wird per Knopfdruck erzeugt (IB_ExportInvoices_Click)
2. DropDown wird gebunden
3. Datei wird zum Download angeboten

Das passiert alles automatisch, bis auf den Knopfdruck natürlich. Kann es sein, dass es an meiner Vermutung liegt? Was gäbe es denn noch für Möglichkeiten, vom UpdatePanel mal abgesehen? Ich habe es mit

Page.Response.Redirect(Page.Request.Url.ToString(), true);

nach dem Dateidownload versucht, klappt auch nicht.

Danke 😃

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

  1. Datei wird per Knopfdruck erzeugt (IB_ExportInvoices_Click)
  2. DropDown wird gebunden und
    ich binde das im Page_Load passt nicht zusammen.
    Binde im Page_Load nur, wenn kein Postback vorliegt. Binde an einer der von mir genannten Stellen, wenn sich die Daten ändern (eine neue Datei dazukommt).

Die Aktualisierung des DropDown und der Dateidownload muss in 2 verschiedenen Requests laufen. Zusammen geht das nicht.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

math55 Themenstarter:in
314 Beiträge seit 2007
vor 13 Jahren

Hallo, ich binde die DropDown einmal im Page_Load, wenn !IsPostBack und dann nochmal nachdem die Datei erstellt wurde. Es gibt also keine Möglichkeit, die DropDown zu aktualisieren?

Grüße

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

doch, natürlich. Und es funktioniert eigentlich genauso wie Du es geade beschrieben hast.
Dein aspx-Code funktioniert bei mir jedenfalls 1:1 wie er oben steht, und ohne UpdatePanel auch.
Besetzt Du die DataSource auch neu vor dem binden? Und wie sieht die aus?

Zeig doch mal den relevanten Code.

Den Download im selben Request abzufädeln heht jedoch nicht, und dafür ist die Page sowieso nicht geeignet, das machst Du besser über einen generischen Handler.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

math55 Themenstarter:in
314 Beiträge seit 2007
vor 13 Jahren

Hallo, aaalso ich habe wie gesagt die DropDownList, diese binde ich im !IsPostBack und nachdem der Button gedrückt wurde. Hier mal der Code zum Binden der DropDown:


private void BindDropDown()
{
	List<string> files = Directory.GetFiles(GetSavePath()).ToList();
	DDL_ExportFileDownLoad.Items.Clear();

	DDL_ExportFileDownLoad.DataBind();
	DDL_ExportFileDownLoad.Items.Insert(0, new ListItem(""));
}

Dazu kommt dann der Code im ButtonEvent:


protected void IB_ExportInvoices_Click(object sender, ImageClickEventArgs e)
{
    File.WriteAllText(fullSavePath, builder.ToString());
    BindDropDown();
    OfferFileForDownload(fullSavePath);
}

So, dann eben noch der Code zum Download:


private static void OfferFileForDownload(string path)
{
	FileInfo downloadFile = new FileInfo(path);
	HttpContext.Current.Response.Clear();
	HttpContext.Current.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", downloadFile.Name));
	HttpContext.Current.Response.AddHeader("Content-Length", downloadFile.Length.ToString());
	HttpContext.Current.Response.ContentType = "application/octet-stream";
	HttpContext.Current.Response.WriteFile(downloadFile.FullName);
	HttpContext.Current.Response.End();
}

Wie würde ich den den HttpHandler bauen, damit er nur den Download handled, ich kann ja den Button nicht per PostBackUrl auf den Handler leiten, da bei Knopfdruck noch andere Dinge passieren (Datei erstellen, einige Überprüfungen etc.), nicht nur der Download. Ich hoffe, der Code reicht aus, wäre für nen guten Tipp sehr dankbar 😃.

Danke

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

so kann das nicht funktionieren aber jaetzt sieht man wenigstens, warum das so ist 🙂

Erstmal ein paar Anmerkungen zum Code:

    List<string> files = Directory.GetFiles(GetSavePath()).ToList();
    DDL_ExportFileDownLoad.Items.Clear();
    // DDL_ExportFileDownLoad.DataSource = files;
    DDL_ExportFileDownLoad.DataBind();

An dieser Stelle willst Du vermutlich die List<string> an die DDL binden. Dazu müsste sie aber als DataSource der DDL gesetzt werden (siehe von mir eingefügte Kommentarzeile).

Du könntest aber auch ganz darauf verzichten, neu zu binden, der ViewState regelt das für Dich. Die Export-Funktion könnte dann etwa so aussehen:

protected void IB_ExportInvoices_Click(object sender, ImageClickEventArgs e)
{
    File.WriteAllText(fullSavePath, builder.ToString());
    DDL_ExportFileDownLoad.Items.Insert(0,new ListItem(Path.GetFileName(fullSavePath)));    
}

In diesem Fall wird immer die neue Datei an die Liste angefügt, die alten Einträge bleiben - ohne erneutes Binden - durch den ViewState erhalten.

Soviel zur Aktualisierung des DropDown.

Jetzt zum Fehler:
Wie ich bereits geschrieben habe, brauchst Du zwei verschiedene Requests, einen für die Aktualisierung der DDL, den anderen für das Ausliefern der Datei.
Möglicherweise würde der Download ohne UpdatePanel sogar funktionieren... aber man sollte in einer Page sowas nicht machen, dafür gibt es die generischen Handler (.ashx), such mal nach HttpHandler bzw. IHttpHandler, da gibt es viele Beispiele hier im Forum.

Wegen des UpdatePanels ist es jedoch unmöglich, daß der Download so funktioniert, da es sich um einen Ajax-Request handelt, bei dem der Client eine ganz bestimmte zum Request passende Antwort haben will, mit der über JavaScript die Seite aktualisiert werden kann. Wenn Du da einfach eine Datei runterschickst, kann der Client damit nix anfangen.

Und wie gesagt: Du kannst nicht 2 verschiedene Dinge in einer einzigen Response machen, also nicht Download und Seitenaktualisierung mischen!!

Ich hoffe das ist jetzt etwas klarer geworden.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo nochmal,

hatte folgenede Passage übersehen, sorry:

Wie würde ich den den HttpHandler bauen, damit er nur den Download handled, ich kann ja den Button nicht per PostBackUrl auf den Handler leiten, da bei Knopfdruck noch andere Dinge passieren (Datei erstellen, einige Überprüfungen etc.), nicht nur der Download. Ich hoffe, der Code reicht aus, wäre für nen guten Tipp sehr dankbar 😃.

Wenn Du weiterhin die Page nutzen musst, um Deine Überprüfungen durchzuführen und die Datei zu erstellen, könntest Du wenn Du fertig bist aus dem Click-Handler per Server.Transfer(...) auf einen generischen Handler umleiten, der die Datei verschickt.

Beachte aber, daß eine gleichzeitige Aktualisierung der Seite auch in dem Fall nicht möglich ist.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca