ASP.Net MVC 2 - Code for master page - asp.net-mvc

I am newbie in MVC and trying to create application in asp.net mvc2. For the common header and footer i wants to use master pages which are having dynamic content, Can anyone please tell me where is the best place to write code for master page. I am trying to add code behind for master page but I am not sure about what is recommended in this situation.

In my opinion, you can create partial views (type of user control) and render it in your master page. Write all the logic to get data from database into partial view's action method. You can write action method in any of your controller. ex. You can create a Layout controller and write action method related to master page. A partial view can also be reusable.
To render your partial view in master page you can write code like :
<div><%= Html.Action("Header", "Layout") %></div>

Related

How to Load Content into an ASP.NET MVC Partial View in a Layout View

'm using ASP.NET MVC 3 with Razor views. I have a partial view which I would like to render on all pages so I am placing it in the site's main Layout page. However, I am not sure the best way to load data into the partial view. I could load it for each ActionMethod but there is there a way to do this globally across the entire app?
Move all the data loading logic for your partial into a separate action method.
Then in your layout page, instead of rendering the partial with a call to RenderPartial(), call the RenderAction() method.
RenderAction() makes a "child" action call - thus putting all the logic needed for that partial into one place.
Write action for this partial view in MasterController because every controller inherits from it, and place your partial view in shared folder and call it on Site's master page (like every site has a user control which gives login box until user is logged in else it displays logged in user info) ... hope it answer your ques ...

Pass data to Master Page with ASP.NET MVC

I have a hybrid ASP.NET WebForms/MVC project. In my Master Page, I have a "menu" User Control and a "footer" User Control. Anyways. I need to pass some data (2 strings) to my "menu" User Control on my Master Page (to select the current tab in my menu navigation, etc.) My views are strongly-typed to my data model. How can I push data from my controller to my menu or at least allow my master page to access some data pre-defined in my controller?
Note: I understand this violates pure ASP.NET MVC, but like I said, it is a hybrid project. The main purpose of my introduction to ASP.NET MVC into my project was to have more control over my UI for certain situations only.
Put your strings into the ViewData collection,
ViewData["MenuString1"] = "My First String";
ViewData["MenuString2"] = "My Second String";
and retrieve them in the Master Page like this:
myMenu.Property1 = ViewData["MenuString1"].ToString();
myMenu.Property2 = ViewData["MenuString2"].ToString();
http://nerddinnerbook.s3.amazonaws.com/Part6.htm
You can use ViewData to share data between the Controller and View that is not in the model. In the Controller, do something like ViewData["menu"] = myMenu; and then in the View do <%= ViewData["menu"] %>. You can pass objects but you need to cast the ViewData[key] back to the object type in the View.
Another way to do this is to put your menus and other non-Model related data needs into a separate controller. Then you can use RenderAction to call the action in your navigation controller that generates the menu. Hack has a blog post on RenderAction that explains this in more detail.
I lean towards using ViewData for temporary values from the controller like select lists and a RenderAction for unrelated things such as the main site navigation.

Populating the model for a shared view, embedding a shared view within another view

I'm trying to embed a small view snippet that steps through a model fragment that works fine when I embed it in a single controller and pass it to a view like so;
Controller:
return View(_entities.formTemplate.ToList());
View:
http://www.pastie.org/666366
The thing is that I want to be able to embed this particular select box in more than just this single action / view, from the googling I've been doing this appears that it should go into a shared view, but I'm not clear then on how I could populate the model within that view from the controller? (or maybe I'm completely missing the purpose for shared views?)
In the other MVC framework I'm accustomed to working with there is the concept of a filter where you can call code before or after any action and mod the model as it passes the controller and goes to the view, is such a thing possible in .net mvc?
Any assistance appreciated.
You'll want to use the HtmlHelper method DropDownList() in order to create a input:
<%= Html.DropDownList("id", new SelectList(formBuilder, "ID", "Name")) %>
You probably want to use a ViewUserControl here.
You have a couple of options if you go that route. If it's model data that is easily available, recreate it at the call site of your RenderPartial like so:
<%=Html.RenderPartial("ViewName", new ModelData())%>
If it's data that is dependent on the current model data, then you'll need to pass that data somehow to your partial view.
ASP.Net MVC also has the concept of before/after controller actions. You decorate your controller method with an Attribute that derives from ActionFilterAttribute. In there, you have access to OnActionExecuting and OnActionExecuted.

Where to apply logic for a sidebar control in ASP.NET MVC

Take the example of wanting to have a "Latest news items" sidebar on every page of your ASP.NET MVC web site. I have a NewsItemController which is fine for pages dedicating their attention to NewsItems. What about having a news sidebar appear on the HomeController for the home page though? Or any other controller for that matter?
My first instinct is to put the logic for selecting top 5 NewsItems in a user control which is then called in the Master Page. That way every page gets a news sidebar without having to contaminate any of the other controllers with NewsItem logic. This then means putting logic in what I understood to be the presentation layer which would normally go in a Controller.
I can think of about half a dozen different ways to approach it but none of them seem 'right' in terms of separation of concerns and other related buzz-words.
I think you should consider putting it in your master page. Your controller can gather data (asynchronously, of course), store it in a nice ViewModel property for your view (or in TempData) and then you can call RenderPartial() in your master page to render the data.
The keeps everything "separate"
http://eduncan911.com/blog/html-renderaction-for-asp-net-mvc-1-0.aspx
This seems to address the question - even using the instance of a sidebar - but using a feature not included with MVC 1 by default.
http://blogs.intesoft.net/post/2009/02/renderaction-versus-renderpartial-aspnet-mvc.aspx
This also indicates the answer lies in RenderAction.
For anyone else interested, here's how I ended up doing it. Note you'll need to the MVC Futures assembly for RenderAction.
Basically you'd have something like this in your controller:
public class PostController
{
//...
public ActionResult SidebarBox()
{
// I use a repository pattern to get records
// Just replace it with whatever you use
return View(repoArticles.GetAllArticles().Take(5).ToList());
}
//...
}
Then create a partial view for SidebarBox with the content you want displayed, and in your Master Page (or wherever you want to display it) you'd use:
<% Html.RenderAction<PostController>(c => c.SidebarBox()); %>
Not so hard after all.
You can create a user control (.ascx) and then call RenderPartial().
Design a method in your controller with JsonResult as return type. Use it along with jQuery.
Use RenderAction() as suggested by elsewhere.
News section with ASP.NET MVC

UI composition in ASP.NET MVC

How would you go about supporting external composable parts in an ASP.NET MVC view?
What do I mean by this? Think either "login box on every page" or "iGoogle". It's stuff that needs to be in certain places that is external to each controller/view.
One approach at this would be adding components in the view like so:
<% foreach (var component in GetComponents()) {%>
<%= Html.RenderPartial(component.ViewName, component.ViewData)%>
<%} %>
In the example above I'm looking for a good way to have the viewname and viewdata delivered by each component's controller and not the controller of the view they are displayed on. Any totally different solution you can suggest would also be of interest. Filters, WebForms, etc.
Update: I'll try to explain what I'm trying to wrap my head around with an example. I'll pick the login functionality.
In a typical webforms application this could be a user control that retrieves the appropriate data in the load event of the page's life cycle and updates some UI controls. Upon click the page would post back and we can act upon the posted information in the click event in the same user control.
As of my current understanding of the ASP.NET MVC style the controller that first accepts the request would retrieve the appropriate data and pass it to the view which in turn would pass it along to the login partial view. The login view would define a form whose post action is directed at the login action of the login controller. The posted information is used by the login action and we can choose to pass the request along to the original controller using some nifty scheme.
I assume there is a smarter approach than the above that doesn't require I put controller logic in a view/a master page.
There is two ways you can do this:
One: Make a BaseController, that allways gets the data needed for these components, set the ViewData["loginbox"] = loginBoxData, and then you can pass it along like so.
<% foreach (var component in GetComponents()) {%>
<%= Html.RenderPartial(component.ViewName, ViewData[component.Name])%>
<%} %>
The problem about this method is that you need to have logic to say WHEN all these data needed for the components is going to be fetched, and when not to.
TWO:
There is a MVC Futures DLL that you can download from here.
It you reference that, and remember to add its namespace to your web.config, then you should be able to say: Html.RenderAction("blah") - this method makes the full trip by contacting a controller, initiate the view, and returns the HTML.
You could use the master page and use content placeholders for view content pages and view user controls.
The default project template in ASP.NET MVC Framework Beta has a content placeholder for the View Content Page. There is also a View User Control for the login/logout link at the top right corner of the pages.
View Content Page
The view content pages are supposed to be used with the data that comes from the View that you are looking at. I.e. if you're browsing to the Index action in HomeController, the server will render the Home/Index.aspx view content page.
In the master page you need the following line:
<asp:ContentPlaceHolder ID="Holder1" runat="server" />
And in the view content page itself you compose for that place holder with the following:
<asp:Content ID="Content1" ContentPlaceHolderID="Holder1" runat="server">
<p>This text goes to "Holder1" content place holder and
I can access the ViewData.</p>
<p><%= ViewData["Message"] %>
</asp:Content>
Each asp:ContentPlaceHolder corresponds to the view's asp:Content through the id. So if you want several placeholders like this:
<asp:ContentPlaceHolder ID="Holder1" runat="server" />
<asp:ContentPlaceHolder ID="Holder2" runat="server" />
…you can handle them in the view content page like this:
<asp:Content ID="Content1" ContentPlaceHolderID="Holder1" runat="server">
<p>This text goes to "Holder1" content place holder</p>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="Holder2" runat="server">
<p>This text goes to "Holder2" content place holder</p>
</asp:Content>
View User Controls
View user controls can be used regardless of what view you are looking at. Here are some examples of viewing user controls, are taken from Wekeroad's blog post about View User Controls. To use a view user control:
<%=Html.RenderUserControl(“~/UserControls/UserList.ascx”)%>
If you have the need you can also pass data and anonymous types to it.
<%=Html.RenderUserControl(“~/UserControls/UserList.ascx”,ViewData.Users, new {GroupID=2})%>
without understanding the question properly, i'd suggest a masterpage approach. ie. have the masterpage render the components and pages derive from the masterpage.
i fear this is not a good answer however. i dont understand this: "..have the viewname and viewdata delivered by each component's controller and not the controller of the view they are displayed on."
This is an old question but here's my take on it with razor:
In CQRS style apps you can push an ICommand to a single service endpoint and the service figures out how to route it.
a good example of this: https://github.com/ncqrs/ncqrs/blob/master/Framework/src/Ncqrs/Commanding/ServiceModel/CommandService.cs
What say - instead of trying to execute a command we were trying to execute a query?
And instead of 1 we were passing 1 or more as a list of IViewModelExecutor?
In your main page you have a master ViewModel it has a definition for each of it's sub ViewModels, when the page loads we ask the service to get all the view models pertaining to this view:
service.Load(new List<IViewModelExecutor>{UserinfoViewModel, UserAccountViewModel });
the service loads the data from the readmodel and caches where needed. The sub view models are passed to the sub views using Html.RenderPartial("subviewname", Model.SubViewModel)
The sub view knows how to render itself based on the model.
Now - as we have a compositional UI with ajax updates - lets say we want to update the UserAccount part of the page. In the controller we have an action that is responsible for rendering JUST that part.
it can also request from the service.Load(new List<IViewModelExecutor>{UserAccountViewModel })
and only get back the part of the view model it needs - probably cached. unless the params change obv.
Now we have a compositional UI that can be constructed in whole or in part.
And using content negotiation we can serve HTML fragments, JSON or XML depending on the HTTP headers in the request.

Resources