MVC 3 using @model twice

2019-09-01 09:37发布

问题:

I would like to using two times @model to get data from another part of my website is it possible? Because now I have got error but if I have only this first @model everything working correct.

Look -> MVC 3 - Exception Details: System.InvalidOperationException

Error 2 'SportsStore.Entities.Kategorie' does not contain a definition for 'Opis' and no extension method 'Opis' accepting a first argument of type 'SportsStore.Entities.Kategorie' could be found (are you missing a using directive or an assembly reference?) c:\Users\Rafal\Desktop\MVC ksiązka\moj projekt\sklep\SportsStore.WebUI\Views\Product\List.cshtml 16 4 SportsStore.WebUI

@model IEnumerable<SportsStore.Entities.Towar>
@model IEnumerable<SportsStore.Entities.Kategorie>


@{
    ViewBag.Title = "List";
}

<h2>List</h2>

@foreach (var p in Model)
{
    <div class="item">
         <h3>@p.Nazwa</h3>
         @p.Opis
         <h4>@p.Cena.ToString("c")</h4>
    </div>
}

回答1:

You only can have one Model per View. But you can use another object to declarate the model:

public class SomeViewModel
{
   public IEnumerable<Towar> Towars;
   public IEnumerable<Category> Categories;

   public SomeViewModel(IEnumerable<Towar> towars, IEnumerable<Category> categories) {
     Towars = towars;
     Categories = categories;
   }
}

And then use it in your view like this:

@model SportsStore.Entities.SomeViewModel

@foreach (var item in Model.Towars)
{
  <div class="item">
    <h3>@p.Nazwa</h3>
    @p.Opis
    <h4>@p.Cena.ToString("c")</h4>
  </div>
}
@foreach (var item in Model.Categories) {
  @item.Name @* or what you need down here *@
}

I would also recommend you to use english names in MVC. It's more clear to read and understand ;).



回答2:

I think this would be a case to create a ViewModel (to combine the two entities you have) and then base a View off that ViewModel.



回答3:

It is best to create a view model to represent your data. Your view model must only contain what you need to display on your view. Anything that is not used you can remove, no point of it being there. Your view model can look like this:

using SportsStore.Entities;

public class YourViewModel
{
     public IEnumerable<Towar> Towars { get; set; }

     public IEnumerable<Kategorie> Categories { get; set; }  // I assume this is categories
}

Lets say that you have to use this view model in a create view then your create action can look something like this:

public class YourController : Controller
{
     private readonly ITowarRepository towarRepository;
     private readonly ICategoryRepository categoryRepository;

     public YourController(ITowarRepository towarRepository, ICategoryRepository categoryRepository)
     {
          this.towarRepository = towarRepository;
          this.categoryRepository = categoryRepository;
     }

     public ActionResult Create()
     {
          YourViewModel viewModel = new YourViewModel
          {
               Towars = towarRepository.GetAll(),
               Categories = categoryRepository.GetAll()
          };

          return View(viewModel);
     }
}

And then in your view:

@model YourProject.DomainModel.ViewModels.YourViewModel

@foreach (var towar in Model.Towars)
{
     // Do whatever
}

@foreach (var category in Model.Categories)
{
     // Do whatever
}