2014-02-10 78 views
0

我有一個簡單的HomeController與一個重載(GET/POST)索引方法,它顯示一個HTML表中的Person對象列表中的數據,併爲用戶提供一個表單他們可以輸入工作表名稱和文件名並下載結果的Excel文件(EPPlus Excel library)並下載它們。要封裝救我創建了以下視圖模型的Excel文件所需的信息:在ASP.NET MVC 4中的擴展方法HttpPost ActionResult

public class ExcelDownloadView 
    { 
     public List<Person> Persons { get; set; } 
     //ConvertToDataTable is a List extension method return converts the list and its properties 
     //into a table where columns are the properties 
     public DataTable DataTable { get { return Persons.ConvertToDataTable(); } } 
     public string SheetName { get; set; } 
     public string FileName { get; set; } 
    } 

這裏是我的觀點的樣子,並在最初的GET請求,一切都出來罰款:

@model ExportToExcel.Models.ExcelDownloadView 
@using ExportToExcel.Helpers 
@{ 
    ViewBag.Title = "Index"; 

} 
<div id="grid"> 
@Html.ListToTable(Model.Persons) 

</div> 
<div> 
This is the number of rows: @Model.DataTable.Rows.Count (correct) 
</div> 


    @using (Html.BeginForm()) 
    { 
     <input name="sheetName" type="text" /><br /> 
     <input name="fileName" type="text" /><br /> 
     <input type="submit" value="Click to download Excel file..." /> 
    } 

當我嘗試提交表單我在ConvertToDataTable方法得到一個錯誤:

public static DataTable ConvertToDataTable<T>(this List<T> data) 
     { 
      DataTable dt = new DataTable(); 
      PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); 
      for (int i = 0; i < props.Count; i++) 
      { 
       PropertyDescriptor prop = props[i]; 
       dt.Columns.Add(prop.Name, prop.PropertyType); 
      } 
      object[] values = new object[props.Count]; 
      //*****error is at the start of the foreach loop 
      foreach (T item in data) 
      { 
       for (int i = 0; i < values.Length; i++) 
       { 
        values[i] = props[i].GetValue(item); 
       } 
       dt.Rows.Add(values); 
      } 
      return dt; 
     } 

控制器:

[HttpGet] 
     public ActionResult Index() 
     { 
      ExcelDownloadView model = new ExcelDownloadView(); 
      model.Persons = Person.GetPersons().ToList(); 
      var dataTable = model.Persons.ConvertToDataTable(); 
      return View(model); 
     } 
     [HttpPost] 
     public ActionResult Index(ExcelDownloadView viewModel) 
     { 
      //DataTable property takes the List<Person> of the view model and turns it into 
      //a datable for use in the following Excel-file-creating function 

      /*--> if nonWorkingVersion is commented out, the program programs with a NullReferenceException*/ 
      //DataTable nonWorkingVersion = viewModel.DataTable; 
      //if a re-seed the DataTable, everything works fine 
      DataTable dt = Person.GetPersons().ToList().ConvertToDataTable(); 

      using (ExcelPackage pck = new ExcelPackage()) 
      { 
       //Create the worksheet 
       ExcelWorksheet ws = pck.Workbook.Worksheets.Add(viewModel.SheetName); 

       //Load the datatable into the sheet, starting from cell A1. Print the column names on row 1 

       ws.Cells["A1"].LoadFromDataTable(dt, true); 
       //Format the header for column 1-3 
       using (ExcelRange rng = ws.Cells["A1:C1"]) 
       { 
        rng.Style.Font.Bold = true; 
        rng.Style.Fill.PatternType = ExcelFillStyle.Solid;      //Set Pattern for the background to Solid 
        rng.Style.Fill.BackgroundColor.SetColor(Color.FromArgb(79, 129, 189)); //Set color to dark blue 
        rng.Style.Font.Color.SetColor(Color.White); 
       } 

       //Example how to Format Column 1 as numeric 
       using (ExcelRange col = ws.Cells[2, 1, 2 + dt.Rows.Count, 1]) 
       { 
        col.Style.Numberformat.Format = "#,##0.00"; 
        col.Style.HorizontalAlignment = ExcelHorizontalAlignment.Right; 
       } 

       //Write it back to the client 

       Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 
       Response.AddHeader("content-disposition", "attachment; filename=" + viewModel.FileName); 
       Response.BinaryWrite(pck.GetAsByteArray()); 
      } 
      return View(viewModel); 
     } 

在GET版本的Index方法中,數據在那裏並且是正確的。爲什麼我的POST版本中的數據沒有正確顯示?如果我修改視圖並刪除對Persons屬性的引用,將會彈出一個診斷對話框,我可以下載我想要的文件。爲什麼POST版本不能從GET版本接收人員的數據?

回答

1

首先要意識到這些操作是針對兩個單獨的請求調用的。首先在用戶導航到頁面時調用,第二次在用戶看到頁面,填寫表單並提交時調用。

接下來是在ASP.NET MVC中你沒有狀態的事實。您所擁有的唯一信息是發佈表單客戶端。所以,即使在前一個請求中創建了一些對象,但這個對象與當前請求無關。在你的表單中有兩個輸入 - 這些是你請求的部分。

正確的方法來處理這是你已經實現。這就是說,如果您在請求期間需要查詢某個數據庫 - 通常您需要在每次請求時執行此操作。

+0

幾乎我所想的,但不確定。我不知道是否使用靜態方法來幫助初始化數據是問題的一部分;它知道它不會讓我省時。謝謝。 – wootscootinboogie