ASP.NET MVC 3, Razor Layout Controller-like? - asp.net-mvc

Haven't found anything about how to do this. I Require some code to run to update data in my Razor Layout.
I could do this by running the code in every Action that is using the Layout and setting ViewBag data, but that seems impracticable...
So, how would i do this in a better way?

The answer to this question, proposes to use a global action filter.
That is a piece of code (filter) that is executed on every action, you can use it, to set properties in the ViewBag. These properties are accessible from every View, and from the layout.

If the data you are rendering in your layout is orthogonal to the data of your actual view (which it should be, or otherwise you are using layouts where you should be using partial views), then imho the conceptually most sound method would be to employ a child action (i.e. using Html.Action) to render the data into the layout.

Related

Accessing session data from a layout

In my ASP.NET MVC solution I have a number of services.
One of them, SessionService, is used to access the currently selected region and time span.
I want to display those in a layout used to decorate views. What is the best design approach to access those values which are stored in the SessionService?
Right now I'm thinking about using calling a ChildAction from the layout which in turn calls the session service:
_Layout -> aController.ChildAction() -> SessionService.GetRegion()
Is it a good approach or can you recommend anything better?
UPDATE 1:
Other options for passing the values that are possible:
via ViewBag
via ViewModels
However the drawback for these options is the fact that it would be necessary to populate them in each and every action method which would lead to duplication of code (which could be mitigated by means of a filter, but again this will require decorating controllers with the filter).
UPDATE 2 (born in the discussion with O:rvar below):
Another option is to create a base controller which will be populating ViewBag properties upon creation. All other controllers should derive from it.
You should be able to access you session data in the view with the following code:
var region = #Session["Region"].ToString();
Or you could call the controller method as you mentioned with an ajax call and get the session data that way. Using the childaction approach is also a fine way of accomplishing what you want.

MVC embed data in Master Layout without violating standards

I have a master layout for a conference registration system, what I'm trying to do is to display the number of registered users in the master layout.
What is the best way to do that ?
I can call a static method to get this count, but from my knowledge, this is a violation of the MVC standards, because interaction between a page and the server should be only through Controller/Action method.
So what is the best way to do this ?
When I need to display data in the layout page, particularly if it's a small amount of data, I usually put that data into ViewBag/ViewData. Otherwise you need a base class model that every developer has to remember to inherit from to carry the data into the view. The ViewBag/ViewData can then be populated by an OnResultExecuting filter on the base controller class.
You need to have main Model/ViewModel for all of your pages or use two or multiple Models/ViewModel in targeted pages. In this way you pass all required data to view via controller methods perhaps by calling a static method in methods. see the following articles to employ the above techniques:
Two models in one view in ASP MVC 3
Multiple models in a view
Another way is storing related data in ViewBag or ViewData Dynamic types in controller methods each time needed and then prepare and use them in View. Note that using them should be avoided in favor of using strongly typed ViewModels.
cheers.

g:include vs g:render

I have a question about pros and cons of g:render and g:include.
In my application I have a piece of code that shows some information that have to be repeated in some gsp, what it show depends on a little bit of logic.
I have a doubt is it better use a g:include or a g:render???
So, is it better to execute the logic on a controller that pass a model to the page that use a layout included with the g:render, or is better to put a g:include to another action in another controller in the gsp that execute the logic of that piece?
I prefer the second choice, but how much it impact on the performance?
They are just used in different cases. You use <g:include .../> when you have a controller that is returning a piece of content that is easily embedded in multiple GSPs. This is also useful if you have a high volume of traffic where you are actually caching at the controller level since you can eliminate a lot of overhead.
<g:render.../> is useful when you need modularity within your page. Especially for AJAX calls where you may initially load one portion of the page then want to update it based on some AJAX event.
Both can be used to reuse content, and both are appropriate in the right context.
g:render is useful while you are working on partial templates and you have the model you need etc.
However, when you need additional (or extensive) progress to pass extra, more meaningful things to your view(template), it is better to use g:include.
By using g:include you will also have a nice controller and that means much more readable code using that controller.
And there would be no performance comparison between 'passing to a controller action and render a view with doing no additional operation' and 'render a view'.

Rendering Navigation in MVC3

What's the best way to render Navigation in MVC3? In my app the Controller has to decide what should be in the Navigation but as far as I know there's no way to pass a Model up to the _Layout file (where the Navigation html lives) to give it this information.
You can make the model available to your layout.
Define a base class, MyBaseModel, with the properties you want available to the layout.
Have your models subclass MyBaseModel, and ensure that you populate the properties
Have your layout specify #model MyBaseModel
Use the properties
See also this blog post where a similar problem ("we often find ourselves needing to include the same information in every page") is tackled.
Best is a relative and subjective term. I would usually go with an approach similar to druttka's answer but another option is to use RenderAction() to invoke a controller action
<div>#Html.RenderAction("action", "controller")</div>
I will offer some counterpoints to #druttka's answer. But mostly, you have to decide which trade off you want to make.
If you use a model for your view, you are now forcing 2 things:
Every view must be strongly typed
Every action must call the function to populate all levels of nav included in your view model
The first point isn't so bad, because there are very few pages in a typical non-static site which wouldn't derive from a model anyway, and its easy enough to create an empty model for those pages. The second point is much more annoying however. Each function has to instantiate it's own model, and then populate the nav properties for every level of nav provided by the model. This can be quite cumbersome, but can be fairly elegantly handled in OnActionExecuted for at least nav which is not specific to a given action.
The alternative is to add the nav to the ViewBag. This can be done whenever and does not force you to specify a model for every view, which is great for the flexibility in those cases where you do not need to specify a model. It should be noted however that the ViewBag in asp.net mvc 3 is of type dynamic, which you cannot use as a parameter in a lambda function, thus preventing you from doing something like #Html.DisplayFor(viewBag => viewBag.MainNav) in your layout, which is a real drag. You can still render partial and specify the appropriate DisplayTemplate however.

Is the best approach a typed or not typed view in ASP.NET MVC?

In ASP.NET MVC it's possible to choice between having a typed view were you define in the codebehind what kind of data the view can should expect. But it's also possible to not define this and just pass any kind of data to view in a ViewData container.
What would the best model here or should I mix depending on what kind of data we're talking about (maybe just make sure to have data that's critical to the functionality of the view typed and other data not typed?)? I don't really understand why there is a option here ...
I would recommend always using the strongly typed ViewData... that way you have compile time checking, intellisense, you don't have to do casting in your view, and the ability to refactor your code much easier.
Earlier releases of the framework required you to choose between a ViewData dictionary and strongly typed view model.
Now you can mix the two. Combine this with some of the new features of Preview 5, such as ModelState, validation, and auto-binding to form fields and it becomes more compelling to use the ViewPage for the main model in your view being rendered.
You can still add data to the dictionary in the controller pipeline and request it later on using ViewData["key"] ... or even better ViewData.Get("key") from MvcContrib.
I had this thought too in the past. In my site, I used to strong-type the view, when the view is almost a 1:1 model of the class you are showing. Like showing a list of all users, I type to List, this way I don't need to cast anytime to have the right datatype.
In none specific views, I just strong-type to the most "heavy"/used type.
In forms, the form itself is the type of the view when returning View(form); ....

Resources