2016-03-22 4 views
0

Я пытаюсь импортировать файл Excel. Вот как выглядит мой метод . Что я делаю здесь просто добавить данные первенствовать в данных-таблицы и преобразования данных, что стол в динамический список и возвращает его в метод контроллера:Преобразование значений динамического списка в объект списка

public List<dynamic> ImportFile(Stream stream) 
{ 
    var productList = new List<Products>(); 
    using (var package = new ExcelPackage(stream)) 
    { 
     var currentSheet = package.Workbook.Worksheets; 
     var workSheet = currentSheet.First(); 

     //Creating a DataTable 
     DataTable tbl = new DataTable(); 
     bool hasHeader = true; // adjust it accordingly(i've mentioned that this is a simple approach) 

     //Creating the header 
     foreach (var firstRowCell in workSheet.Cells[1, 1, 1, workSheet.Dimension.End.Column]) 
     { 
      tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column)); 
     } 

     var startRow = hasHeader ? 2 : 1; 
     ////Inserting the stream into DataTable 
     for (var rowNum = startRow; rowNum <= workSheet.Dimension.End.Row; rowNum++) 
     { 
      var wsRow = workSheet.Cells[rowNum, 1, rowNum, workSheet.Dimension.End.Column]; 
      var row = tbl.NewRow(); 
      foreach (var cell in wsRow) 
      { 
       row[cell.Start.Column - 1] = cell.Text; 
      } 
      tbl.Rows.Add(row); 
     } 
     //Convert datatable into dynamic list 
     var dynamicDt = new List<dynamic>(); 
     foreach (DataRow row in tbl.Rows) 
     { 
      dynamic dyn = new ExpandoObject(); 
      dynamicDt.Add(dyn); 
      foreach (DataColumn column in tbl.Columns) 
      { 
       var dic = (IDictionary<string, object>)dyn; 
       dic[column.ColumnName] = row[column]; 
      } 
     } 
     return dynamicDt; 
    } 
} 

Это как мой метод контроллера выглядит :

[HttpPost] 
public ActionResult Upload(HttpPostedFileBase upload) 
{ 
    IExcelImporter reader = new ExcelImporter(); 
    var res = new List<dynamic>(); 
    List<Products> send = new List<Products>(); 
    if (ModelState.IsValid) 
    { 
     if (upload != null && upload.ContentLength > 0) 
     { 
      Stream stream = upload.InputStream; 

      if (upload.FileName.EndsWith(".xlsx")) 
      { 
       //getting the dynamic list(returning dynamic list) 
       res = reader.ImportFile(stream); 

       //need to bind it a model-class(Products) 
       send = res.Select(x=> 
       new Products 
       { 
        ID = res.GetType().GetProperty("ID").ToString(), 
        Name = res.GetType().GetProperty("Name").ToString(), 
        //res.Select(e=>e.Price).ToString()//res.GetType().GetProperty("Price").GetValue(res, null).ToString() 
       }).ToList(); 
      } 
     } 
    } 
    return View("Index", send); 
} 

Вопрос: То, что я хочу, чтобы привязать динамический список к модели класса (продукты). Чтобы я мог вернуть его в представление. Как сопоставить динамический список для списка продуктов?

Это как мой IExcelImporter выглядит следующим образом:

public interface IExcelImporter 
{ 
    List<dynamic> ImportFile(Stream stream); 
} 

Это как моя продукция модель выглядит следующим образом:

public class Products 
{ 
    public string ID { get; set; } 
    public string Name { get; set; } 
    public string Price { get; set; } 

} 

Может кто-то пожалуйста, дайте мне идею, как решить эту проблему. Заранее спасибо.

+1

Что случилось с тем, что вы получили? – Shoe

+0

Я не могу сопоставить динамический список с классом модели (Продукты), чтобы вернуть представление. – Dayan

+0

Похоже, что вы выполняете какое-то отражение, чтобы получить динамические свойства и проецировать их в класс модели. Разве это не работает? Что не так? – Shoe

ответ

1

В общем случае я не вижу причины использовать dynamic в качестве типа возврата. Ваш метод ImportFile может вернуть IEnumerable<Dictionary<string, string>>. Кроме того, почему DataTable? Я предполагаю, что вы используете много copy-paste из другого примера, который использует DataTable для использования базы данных, лучше создать дополнительный список для хранения имен столбцов и использовать их в качестве ключей в словаре, это сэкономит вам много Кастинг. Если вы не показываете очень упрощенный пример, ваш метод ImportFile имеет множество накладных расходов, как с точки зрения удобочитаемости, так и с точки зрения производительности.

Чтобы получить ответ на свой вопрос, хотя,

Здесь вы получаете PropertyInfo из несуществующего имущества «ID» из List<dynamic> - не то, что вы хотите.

res.GetType().GetProperty("ID").ToString() 

вместо этого вы должны использовать

// Get value of dynamic property "ID" of an item when iterating over of List<dynamic> 
x.ID.ToString() 
Смежные вопросы