2010-07-01 37 views
7

我有一箇中繼器,顯示各種股票的財務數據和價格。如何在回發之後堅持來自轉發器的數據?

在這個頁面上,我還有一個「導出」按鈕,需要將屏幕上的數據〜轉換爲用戶的CSV格式。

的問題是,在我的數據綁定我的「股票」實體名單:

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

的數據不會保留在回發。

此外,此頁上的數據不斷通過UpdatePanel和Timer控件更新(每次重新綁定數據)。每30秒鐘,中繼控制器中各種股票的價格變化。

現在,我有一個鏈接按鈕,它在代碼隱藏方面有一個點擊事件方法,它應該在屏幕上爲用戶導出〜數據。我需要抓住最後一個數據庫股票列表的當前值到中繼器。我不能簡單地從數據庫中獲取最新值,因爲這些值在上次刷新之間的時間內會發生變化。

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

我知道,ASP.NET不會持續在後回中繼器的數據源,但我需要仍然能夠要麼重新構建股票的實體名單,所以我可以把他們的CSV或者我需要以某種方式堅持下去。

我不想在性能方面做任何過於沉重的事情,因爲在一週中的某些日子裏,這個應用程序可能會有一些沉重的用法。

這種情況的適當解決方案是什麼?我是否應該遍歷Repeater的「Items」集合並重建股票實體?

+1

我認爲你需要發佈一些關於'ExportStocksToExcel()'的具體信息,因爲轉發器不應該丟失綁定到它的數據(假設你沒有禁用控件或頁面上的viewstate),因爲viewstate 。但是,如果這是您的預期(或至少以任何合理的方式),則無法從中繼器讀取數據源中的數據。 – 2010-07-01 18:58:32

+0

@Chris Marisic,因此,根據我上面寫的內容,您將如何親自從中繼器獲取數據以輸出CSV? – Darwin 2010-07-01 19:02:09

+0

@Chris Marisic,截至目前,所有ExportStocksToExcel()都會設置正確的標題和內容類型,然後我將寫出一份有關CSV數據的響應。但是,我很難弄清楚如何將數據恢復出來。 – Darwin 2010-07-01 19:03:04

回答

0

這聽起來像你的Page_Load方法,你正在做一些綁定到你的中繼器。出於您的目的,這是不好的,正如您所看到的,它將在每次回發時不執行您的數據。你能確保你的Page_Load事情是這樣的嗎? :

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

    //stuff 
    //databinding stuff 
    } 
} 
+1

這就是我現在擁有的東西。這是如何幫助我調用導出鏈接按鈕時,數據不會持久的事實? – Darwin 2010-07-01 18:36:36

+0

@達爾文數據可能會持續存在。例如。如果中繼器包含用戶可設置的文本框,列表框或複選框,則除非您調用'DataBind',否則這些值* ARE *在回發時保留。所以你的數據*可能*已經在'ViewState'中。你可以通過一個runat =「server」按鈕進行檢查,該按鈕除了導致回發之外什麼也不做。如果你的數據*被*保留,它應該在點擊那個按鈕後仍然存在。 – 2010-09-06 10:40:56

1

您可以將stocks存儲在Viewstate或Session中嗎?例如

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"]; 
    ... 
} 

會話狀態,實際上可能是更好的選擇,用於存儲Stocks因爲這將不會在頁面傳輸到客戶端(與「創意編輯」,可能意味着一切準備) - 這可能是非常重要的在這樣的應用程序中。 (是的,你可以加密Viewstate,但要注意那些高峯時間,這可能是你不想要的開銷。)

0

我會帶Phil的答案並序列化整個數據集,或者創建一些標準對象傳遞給GetStocks()來指定要獲取的數據。然後序列化並將標準對象存儲在ViewState中,因此當用戶單擊「導出」時,可以拉取標準並檢索相同的數據。

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

然後GetStocks()具有StockCriteria作爲參數並基於它的查詢。

+0

我想,您可能想要通過一個時間點,否則股票的價格可能會在DateFrom和DateTo之間發生變化...... – PhilPursglove 2010-07-05 15:50:00

1

一個簡單的方法是將值呈現爲輸入控件(而不是<span>或單純的<td>元素) - 當用戶發佈時,瀏覽器將輸入值發送回服務器。

例如:

<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> 

客戶端發送一個名爲「符號」在一個陣列(命名,同樣的輸入值「報價」),每個輸入值,你可以在你的訪問代碼隱藏這樣的:

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 
} 

當然,在底部,這種技術基本上是寫任何客戶端發送您的Excel文件,所以你可能想保護或限制某種方式輸入。這可能涉及對用戶進行身份驗證和/或限制您的方法將導出的數據量。如果這是你的環境中的一個嚴重問題,或者你不能太在意,請考慮序列化用戶會話中的原始數據。

同樣,如果您有意地傳輸大量數據,您應該考慮使用其他方法出於性能原因。您可以使用會話來代替,或者傳輸一個小密鑰,您可以使用該密鑰來重建用於構建中繼器的數據(例如,如果中繼器綁定到查詢的結果,而該查詢的結果並未根據其輸入發生更改,那麼您可以在調用之間序列化輸入)。