1

I'm trying to use _layouts for a shop site.

Every page has different data with only the left menu data being common. It seems I'm being forced to have a gigantic global model with every possible bit of data represented in it. e.g ShopModel.menu,ShopModel.category,ShopModel.footer,ShopModel.category leader etc. It just goes on forever and gets very deep an complicated.

Is there no way to separate the code so that the menu handles the menu and the category handles the category etc. Seems like a big backward step from Web forms. I tried a _partial with its own @model for the menu but it seems its ignored and the CHTML is still looking for data in the main ShopModel.

Of course on day one I tried adding multiple @models to the page but that doesn't work.

Edit: Unfortunately, I must not explain it very well as I would see this as a first-day problem. I would expect the _layout to contain the MENU @model as its common. I would then expect to add my CATEGORY @model to the index page as it loops Categories in a foreach.

The Html is fine. I know how to add a partial but how do I add a self-sufficient partial with dynamic foreach data for example.?

Iman Bahrampour
  • 6,180
  • 2
  • 41
  • 64
user964787
  • 1,127
  • 2
  • 11
  • 20
  • Of course you can use partials. And for things like menus on layout pages, you would use `@"{ Html.RenderPartial(...); }` to call a controller method that returns a partial –  Oct 10 '17 at 11:17
  • Yes i can use a partial but how do i get this model in without putting it in the pages @model along with every other model on the page. `@foreach (SelectListItem item in Model){ Bla }` Does the @model VerybigViewModel have to contain every model I will ever need on ALL pages.? – user964787 Oct 10 '17 at 11:34
  • Of course not. The model in the view contains only those properties you need in the specific view. And for common items such as menus in layouts you use `@{ Html.RenderAction(); }` to include partials (even if they need models they are not part of the view model because you initialize the in separate controller methods called by `RenderAction` –  Oct 10 '17 at 11:37
  • re your edit: Layouts do not contain a `@model` definition (unless its a base view model used by all other models used by that layout). Again. if you need controller logic to generate you menu, create a `[ChildActionOnly]public ActionResult Menu()` method to generate your model and have it return a partial view. Then use `@Html.Render("Menu")` to include it in your layout –  Oct 10 '17 at 11:46
  • Thanks. Would I be right is saying this is wrong `@await Html.PartialAsync("_Menu")` and yours is right (`@{ Html.RenderAction('Menu'); }`) as it will be totally independent and have its own `@model IEnumerable` and `return View(mymenuViewmodel);` – user964787 Oct 10 '17 at 11:52
  • Firstly `Html.PartialAsync()` is asp.net-core-mvc, so you have not tagged this correctly. But `PartialAsync()` (or `Html.Partial()`) only renders the html of the partial (and you need to pass it a model if it needs one in the 2nd parameter). You need to use `Html.Action()` if you want to call a controller method that generates a separate model, so in your case `@Html.Action("Menu")` (or `@{ Html.RenderAction("Menu"); }` is the correct approach –  Oct 10 '17 at 11:58

2 Answers2

1

ViewComponents seem to be the answer to keep thing neat and separate.

ViewComponents

user964787
  • 1,127
  • 2
  • 11
  • 20
  • Exactly. The primary difference between a PartialView and a ViewComponent is that the PartialView doesn't have it's own model and a ViewComponent does. Here is a related SO question I answered that may be helpful: https://stackoverflow.com/questions/38223072/is-there-any-good-reason-not-to-use-a-viewcomponent-instead-of-a-partial-view-in – RonC Oct 10 '17 at 14:45
0

If the left menu is a common element for the whole system, just put its code in the Layout.cshtml page in the Shared folder. All the visual elements that are common to the whole system can be put there, the Header, this menu, the footer, etc. The _ViewStart.cshtml page at the root of the View folder sets the system to look for the page referenced in its Layout parameter and involve every View it has within it. Partial Views just mean rendering/coding the page body without including this common information.

Tiramonium
  • 557
  • 5
  • 15