2010-07-01 9 views
7

Ich habe einen Repeater, der Finanzdaten und Preise für verschiedene Aktien anzeigt.Wie kann ich die Daten von einem Repeater nach dem Postback beibehalten?

Auf dieser Seite habe ich auch einen "Export" -Knopf, der die Daten ~ auf dem Bildschirm ~ nehmen und in eine CSV für den Benutzer konvertieren muss.

Das Problem ist, nachdem ich meine Liste der „Auf“ Entitäten Databind:

List<Stock> stocks = GetStocks() 
rptStockList.DataSource = stocks; 
rptStockList.DataBind(); 

Die Daten werden nicht auf Postbacks beibehalten.

Außerdem werden die Daten auf dieser Seite ständig über ein UpdatePanel und ein Timer-Steuerelement aktualisiert (jedes Mal neu gebunden). Alle 30 Sekunden ändern sich die angezeigten Preise für die verschiedenen Bestände in der Repeater-Steuerung.

Jetzt habe ich einen Linkbutton, der eine Click-Event-Methode im Code-Behind hat, die die ~ Daten auf dem Bildschirm ~ für den Benutzer exportieren soll. Ich muss die aktuellen Werte für die Liste der Aktien abrufen, die zuletzt an den Repeater gesendet wurden. Ich kann nicht einfach die neuesten Werte aus der Datenbank abrufen, da diese in der Zeit zwischen der letzten Aktualisierung geändert wurden.

protected void lbtnExportStocks_Click(object sender, EventArgs e) 
{ 
    // No longer have the stock data used in the repeater control 
    ExportStocksToExcel(); 
} 

Ich weiß, dass ASP.NET bleibt nicht die Datenquelle für den Repeater auf Post-back, aber ich muss noch in der Lage sein Entitäten entweder neu bauen diese Liste der Lager, so kann ich ihnen die CSV senden oder ich muss es irgendwie beibehalten.

Ich möchte nichts tun, was in Bezug auf die Leistung zu schwer ist, weil an bestimmten Tagen der Woche diese Anwendung stark beansprucht werden kann.

Was ist die richtige Lösung für diese Art von Situation? Soll ich die "Items" -Sammlung des Repeaters durchlaufen und die Stock-Entitäten rekonstruieren?

+1

Ich denke, Sie müssen einige Informationen darüber, was genau ExportStocksToExcel() 'tut, da der Repeater die Daten nicht verlieren sollte, die daran gebunden ist (vorausgesetzt, Sie nicht ViewState auf dem Steuerelement oder der Seite deaktiviert haben) wegen Viewstate . Sie können die Daten jedoch nicht rückwärts vom Repeater aus der Datenquelle lesen, wenn Sie das erwartet haben (oder zumindest auf eine vernünftige Weise). –

+0

@Chris Marisic, also, wenn ich das oben Geschriebene schreibe, wie würden Sie persönlich die Daten vom Repeater zurückbekommen, um eine CSV auszugeben? – Darwin

+0

@Chris Marisic, Im Moment stellt ExportStocksToExcel() den richtigen Header und Inhaltstyp ein und dann würde ich eine Antwort mit den CSV-Daten schreiben. Ich habe jedoch Schwierigkeiten, herauszufinden, wie ich diese Daten wieder herausbekomme. – Darwin

Antwort

0

Es klingt wie in Ihrer Page Load Methode, die Sie eine Art Bindung an Ihren Repeater machen. Für Ihre Zwecke ist das schlecht, und wie Sie gesehen haben, werden Ihre Daten bei jedem Postback nicht angezeigt. Kannst du sicherstellen, dass deine Page_Load-Dateien so aussehen? :

Page_Load(...){ 
    if (! Page.IsPostBack){ 
    //first time page loads do this block 

    //stuff 
    //databinding stuff 
    } 
} 
+1

So habe ich zur Zeit Dinge. Wie hilft das der Tatsache, dass die Daten bei meinem Aufruf der Export-Link-Schaltfläche nicht beibehalten werden? – Darwin

+0

@Darwin Die Daten können persistent sein. Z.B. Wenn der Repeater benutzerdefinierbare Textfelder, Listenfelder oder Kontrollkästchen enthält, werden diese Werte * ARE * beim Postback beibehalten, es sei denn, Sie rufen "DataBind" auf. So können Ihre Daten * bereits im 'ViewState' sein. Sie können dies überprüfen, indem Sie eine runat = "server" -Schaltfläche haben, die nur einen PostBack verursacht. Wenn Ihre Daten * * beibehalten werden, sollten sie nach dem Klicken auf diese Schaltfläche weiterhin vorhanden sein. –

1

Konnten Sie stocks in Viewstate oder in Sitzung speichern? z.B.

List<Stock> stocks = GetStocks() 
rptStockList.DataSource = stocks; 
rptStockList.DataBind(); 

ViewState.Remove("stocks"); 
ViewState.Add("stocks", stocks); 

private void ExportStocksToExcel 
{ 
    List<Stock> persistedStocks; 

    persistedStocks = (List<Stock>)Page.ViewState["stocks"]; 
    ... 
} 

Sitzungsstatus kann tatsächlich die bessere Wahl seine Stocks zum Speichern, da diese nicht an den Client auf der Seite übertragen bekommen (mit allen Möglichkeiten für kreative Bearbeitung ", die zur Folge haben könnten) - das ist wohl ziemlich wichtig in einer Anwendung wie dieser. (Ja, Sie könnten den Viewstate verschlüsseln, aber mit Blick auf diese Spitzenzeiten ist das ein Overhead, den Sie vielleicht nicht wollen.)

0

Ich würde entweder Phils Antwort nehmen und das gesamte Dataset serialisieren, ODER eine Art von Kriterienobjekt erstellen, das ist an GetStocks() übergeben, um anzugeben, welche Daten abgerufen werden sollen. Dann serialisieren und speichern Sie das Kriterienobjekt in ViewState. Wenn der Benutzer also auf "Exportieren" klickt, können Sie die Kriterien abrufen und die gleichen Daten abrufen.

d.h.

[Serializable] 
public class StockCriteria 
{ 
    public DateTime DateFrom { get; set; } 
    public DateTime DateTo { get; set; } 
    public string[] Symbols { get; set; } 
} 

und dann GetStocks() hat StockCriteria als Parameter und erzeugt seine Abfrage darauf basiert.

+0

Sie möchten wahrscheinlich einen einzelnen Zeitpunkt passieren, denke ich, oder der Preis einer Aktie könnte sich zwischen DateFrom und DateTo ändern ... – PhilPursglove

1

Eine einfache Methode besteht darin, die Werte als Eingabesteuerelemente zu rendern (im Gegensatz zu beispielsweise <span> oder bare <td> Elemente) - der Browser sendet Eingabewerte zurück an den Server, wenn der Benutzer sendet.

Zum Beispiel:

<ItemTemplate> 
    Symbol: <input type="text" readonly="readonly" name="Symbol" value="<%# Container.DataItem("Symbol") %> /> 
    Quote: <input type="text" readonly="readonly" name="Quote" value="<%# Container.DataItem("Quote") %> /> 
</ItemTemplate> 

Der Client sendet jeden Eingabewert mit dem Namen "Symbol" in einem Array (und ebenso die Eingangswerte genannt "Quote"), die Sie in Ihrem Code-Behind wie folgt zugreifen können :

protected void lbtnExportStocks_Click(object sender, EventArgs e) { 

    // They come out as comma-delimited strings 
    string[] symbols = Request.Form["Symbol"].Split(','); 
    string[] quotes = Request.Form["Quote"].Split(','); 

    // ... continue exporting stocks to Excel 
} 

natürlich an der Unterseite, diese Technik im Grunde ist das Schreiben, was auch immer der Kunde Sie in eine Excel-Datei sendet, so dass Sie die Eingabe in irgendeiner Weise sichern oder begrenzen könnten wollen. Dies kann die Authentifizierung von Benutzern und/oder die Drosselung der Datenmenge erfordern, die von Ihrer Methode exportiert wird. Wenn dies in Ihrer Umgebung ein ernsthaftes Problem darstellt oder Sie es sich nicht leisten können, dem Produkt große Aufmerksamkeit zu schenken, ziehen Sie in Erwägung, die Originaldaten in der Sitzung des Benutzers zu serialisieren.

In ähnlicher Weise, wenn Sie absichtlich Übertragung einer großen Datenmenge sind, sollten Sie aus Leistungsgründen andere Ansätze verwenden. Sie können stattdessen die Sitzung verwenden oder einen kleinen Schlüssel senden, mit dem Sie die zum Aufbau des Repeaters verwendeten Daten rekonstruieren können (z. B. wenn der Repeater an die Ergebnisse einer Abfrage gebunden war, die sich bei seinen Eingaben nicht ändert kann nur die Eingabe (n) zwischen Anrufen serialisieren).

Verwandte Themen