What I see is a string Layout property. But how can I pass a model to layout explicitly?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- MVC-Routing,Why i can not ignore defaults,The matc
- Generic Generics in Managed C++
- Why am I getting UnauthorizedAccessException on th
A common solution is to make a base view model which contains the properties used in the layout file and then inherit from the base model to the models used on respective pages.
The problem with this approach is that you now have locked yourself into the problem of a model can only inherit from one other class, and maybe your solution is such that you cannot use inheritance on the model you intended anyways.
My solution also starts of with a base view model:
What I then use is a generic version of the LayoutModel which inherits from the LayoutModel, like this:
With this solution I have disconnected the need of having inheritance between the layout model and the model.
So now I can go ahead and use the LayoutModel in Layout.cshtml like this:
And on a page you can use the generic LayoutModel like this:
From your controller you simply return a model of type LayoutModel:
For example
Read more about the new @model directive
Let's assume your model is a collection of objects (or maybe a single object). For each object in the model do the following.
1) Put the object you want to display in the ViewBag. For example:
2) Add a using statement at the top of _Layout.cshtml that contains the class definition for your objects. For example:
@using YourApplication.YourClasses;
3) When you reference yourObject in _Layout cast it. You can apply the cast because of what you did in (2).
Maybe it isnt technically the proper way to handle it, but the simplest and most reasonable solution for me is to just make a class and instantiate it in the layout. It is a one time exception to the otherwise correct way of doing it. If this is done more than in the layout then you need to seriously rethink what your doing and maybe read a few more tutorials before progressing further in your project.
then in the view
in .net core you can even skip that and use dependency injection.
It is one of those areas that is kind of shady. But given the extremely over complicated alternatives I am seeing here, I think it is more than an ok exception to make in the name of practicality. Especially if you make sure to keep it simple and make sure any heavy logic (I would argue that there really shouldnt be any, but requirements differ) is in another class/layer where it belongs. It is certainly better than polluting ALL of your controllers or models for the sake of basically just one view..
Use IContainsMyModel in your layout.
Solved. Interfaces rule.
Example: Controller:
Example top of Layout Page
Now you can reference the variable 'viewModel' in your layout page with full access to the typed object.
I like this approach because it is the controller that controls the layout, while the individual page viewmodels remain layout agnostic.
Notes for MVC Core
Mvc Core appears to blow away the contents of ViewData/ViewBag upon calling each action the first time. What this means is that assigning ViewData in the constructor doesn't work. What does work, however, is using an
IActionFilter
and doing the exact same work inOnActionExecuting
. PutMyActionFilter
on yourMyController
.