Как распечатать список из ViewBag - PullRequest
0 голосов
/ 05 июня 2018

Я хочу напечатать информацию о товаре вместе с названием категории.Я использовал ViewBag для этого. Как получить к нему доступ или распечатать его. Вот классы доменов и класс контекста

public partial class Category  
{  
public int CategoryID { get; set; }  
public string CategoryName { get; set; }  
public string Description { get; set; }  
public byte[] Picture { get; set; }  
}

public partial class Product
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public Nullable<int> SupplierID { get; set; }
public Nullable<int> CategoryID { get; set; }
}

, а метод Action -

public ActionResult Products()
    {
        var productList = (from p in db.Products
                          join c in db.Categories 
                          on p.CategoryID equals c.CategoryID
                          select new { ProductID=p.ProductID, ProductName=p.ProductName, CategoryName =c.CategoryName }).ToList();
        ViewBag.ProductsList = productList;
        return View();
    }

и представление Products.cshtml имеет вид

 <table border="1" cellpadding="1" cellspacing="1" style="border:dotted">
<thead>
    <tr>
        <th>Produdt Id</th>
        <th>Name</th>
        <th>Category</th>
    </tr>
</thead>
<tbody>
    @foreach(var item in ViewBag.ProductsList)
    {
        <tr>
            <td>@item.ProductID</td>  
            <td>@item.ProductName</td>
            <td>@item.CategoryName</td>
        </tr>
    }
</tbody>

Возвращается исключение.
Сведения об исключении: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
«объект» не содержит определения для «ProductID»
Пожалуйста, исправьте меня.и большое спасибо

1 Ответ

0 голосов
/ 05 июня 2018

Как отмечалось, вы должны стараться избегать ViewBag и использовать вместо этого строго типизированные ViewModels.

При этом ваша проблема в том, что ViewBag в основном IDictionary<string, object>.Поэтому, если вы получите доступ к ViewBag["ProductsList"], вы получите object, и, следовательно, ошибка

'object' не содержит определения для 'ProductID'

Вам нужно привести этот object к исходному типу, чтобы получить доступ к свойствам.Но у вас нет исходного типа для приведения, потому что вы в первую очередь использовали анонимный тип для заполнения ViewBag.

Чистое решение - ввести ViewModels:

public class ProductViewModel {
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    public string CategoryName { get; set; }
}

public class ProductsPageViewModel {
    public ProductsPageViewModel {
        ProductsList = new List<ProductViewModel>();
    }

    public ICollection<ProductViewModel> ProductsList { get; set; }
}

PassViewModel для View в контроллере:

public ActionResult Products() {
    var productList = 
        (from p in db.Products
         join c in db.Categories 
         on p.CategoryID equals c.CategoryID
         select new ProductViewModel { 
             ProductID = p.ProductID, 
             ProductName = p.ProductName, 
             CategoryName = c.CategoryName 
         }).ToList();

    var viewModel = new ProductsPageViewModel {
        ProductsList = productList 
    };
    return View("Products", viewModel);
}

В представлении Products.cshtml определите, какую ViewModel вы ожидаете, с помощью директивы @model:

@model ProductsPageViewModel 

@* ... *@

@foreach (var item in Model.ProductsList) {
    @item.ProductID
}
...