ASP.Net MVC 3 Razor: how to create and pass info to a dynamic layout
In other languages (PHP/Python), I am used to creating a class which represents a given HTML page layout. These classes can have an unlimited number of attributes and dynamic features, such as Navigation (multi level), error messages, info messages, footer text, etc... Most of these items have defaults, but may be overridden on a per-page level. For example:
Layout = MainPage()
Layout.Title = "Google Image Search"
Layout.Nav1.Add("Google", "http://www.google.com", Selected=True)
Layout.Nav1.Add("Yahoo", "http://www.yahoo.com")
Layout.Nav1.Add("Bing", "http://www.bing.com")
Layout.Nav2.Add("Google Image Search", "http://......", Selected=True)
Layout.Nav2.Add("Google Shopping Search", "http://......")
Layout.Nav2.Add("Google Video Search", "http://......")
Layout.Nav2.Add("Google Web Search", "http://......")
or, handling errors:
try:
# do something
except ValidationError as e:
Layout.Error.Add(e)
or a php example:
$Layout->Info[] = "Your changes have been saved!";
My question is: how do I implement similar functionality into ASP.Net MVC 3 Razor (VB)?
So far, I have been able to see how you can use ViewData
to pass various bits of data to a view. Also, I have been working with strongly 开发者_如何学运维typed views.
Frankly, I'm not sure who's job it is to have this logic, the controller or the view (or is there a model that should be in there somewhere).
Here is a summary of what I am shooting for:
- A single place to initialize the default values for the layout (like the first layer of navigation, etc...)
- Strongly typed attributes, such as
Public Readonly Property Nav1 as List(of NavElement)
- And a single place to render these layout elements (I assume
_Layout.vbhtml
)
Please forgive the here-and-there of this post... I'm trying to figure out the "right way" it's done on a platform that is both new (Razor) and new to me (ASP.Net MVC).
General advise very welcome!
I usually have a controller property (MainMenu
) which I add to the ViewData
dictionary in Controller.OnResultExecuting
in my BaseController. Note that it's named ViewBag
in mvc3 and it's a dynamic object.
Another approach would be to use sections in razor. Look at this question: ContentPlaceHolder in Razor?
I lean toward the fat models, skinny controllers perspective. If it were me I would create a base class for your page models that provides support for your common data. You can then inherit from that for individual page models and store your page specific data there.
The MVC implementations that have worked well for me usually have relatively clean Controllers. The controller is just the connector, getting the data from the request into the model and then handing off the prepared model to the correct view.
As for how you store collections of things in .Net - look at the classes that implement IEnumerable interface. Specifically focus on the Dictionary and the List classes. Dictionary objects store name/value pairs and can include nested dictionaries. You can work with them almost exactly like you can use multi-dimensional arrays in PHP. List objects are just indexed collections of items of the same type. You can work with them just like a simple array in PHP.
One side note - if you're just getting started in .Net and coming from a PHP/Python background, it might be better if you can switch to C#. You'll find the syntax much more comfortable and the tutorials/examples more plentiful (especially in the asp.net mvc world)
It's not difficult! :-) If layout model is of the same type of the content page, the association is automatic! Here is the simplest example...
This is a test layout:
@model string
<style>
.test
{
background:@Model;
}
</style>
<div class="test">
Ciao
</div>
@RenderBody()
And this is a test content page
@{
Layout = "~/Views/Shared/_Test.cshtml";
}
@model string
...blah blah...
Just call the View with something like:
...
return View("Name", (object)"Green");
and it's done! The model is the same in the content page and in the layout page! Andrea
P.S.: Believe me! This is useful!!! Maybe it's not the best for purists, but it's really useful!!! :-)
精彩评论