I want to insert a user control on to a master page
The user control is a basic menu that lists categories of items
I want to pull the category list dynamically from SQL Server
I can do this in web forms using code behind, but how do you go about this in MVC?
Thank you
Categories.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<ul>
<% foreach (string category in Model.Categories ) { %>
<li>
<%= Html.Encode(category) %>
</li>
<% } %>
</ul>
I would make a base controller for all the controllers that will use your MasterPage. In that base controller I would load up your list of data to create the menu (from a cache, sql, whatever) and store it in ViewData.
If you want to you could also make a base model for all your models that will be loading your views based on the controller as well and then you could just load it directly into the models that extend this base class.
Assuming your went the easier ViewData route, in your user control you can just access the ViewData and load your menu since you can assume that all your contorllers will have pre-loaded this data.
this is in your Controller:
ViewData["CategoryList"] = _categoryService.GetCategoryList();
this exists in a file called NameOfMyPartial.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<% foreach (var category in (IList<Category>)ViewData["CategoryList"])) { %>
// do stuff with category
<% } %>
Then in your Master page:
<% RenderPartial("NameOfMyPartial"); %>
Related
I want to call one div when the page is default.aspx and to call same div at the same time when the page is another page than default.I have done something like this but is not doing correctly.
<% if(string.Compare(Request.Url.LocalPath,"/default.aspx")==0 || string.Compare(Request.Url.LocalPath,"/") ==0)
{%>
<div class="temples" >
<% } %>
<% else
{ %>
<div class="temples" style="display:none";>
<% } %>
You can try like this:
string s = this.Page.Request.FilePath;
This will get you the current request URL from within the master page
Also check the IsMasterPage property:
Gets a value that indicates whether or not a child element in the
viewer should be used as a master page.
There is a property IsMasterPage to define whether your control element associated to master page. Below is a link to get more information.
DocumentViewerBase.IsMasterPage
i have created a area. after that i created the controller and then created the view as list. but the foreach statement is not able to recognize the Model. it is taking it as object but it should be an ienumarable? do i have to configure namespaces in the area somewhere?
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Admin.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<CentralBanking.Models.Currency>>" %>
<% foreach (var item in Model) { %>// error object doesn't contains the public method for geteumerator
casting the Model will solve the problem but it is not i want to do. everything is working fine outside the area
You can see that the other parts of the Inherits type are fully qualified. You must do the same with IEnumerable<>, which belongs in the System.Collections namespace:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Admin.Master" Inherits="System.Web.Mvc.ViewPage<System.Collections.IEnumerable<CentralBanking.Models.Currency>>" %>
This seemed easier in Web Forms; I'd have a user control, with the logic in the code-behind, and I could just drop it on a page.
But apparently code-behinds are a no-no in MVC, and the logic is in controllers. I'm a little confused about how logic for a user control is "wired up".
I want to display an RSS Feed user control. So I have a page:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<p>
<% Html.RenderPartial("RssFeed"); %>
</p>
</asp:Content>
I have my user control:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewPage<SyndicationFeed>" %>
<%# Import Namespace="System.ServiceModel.Syndication" %>
<p>
<%: ViewData.Model.Title.Text %>
</p>
<div>
<% foreach (var item in ViewData.Model.Items)
{
string url = item.Links[0].Uri.OriginalString;
%>
<p><a href='<%= url %>'><b><%= item.Title.Text %></b></a></p>
<% } %>
</div>
And I have this code that I need to run to get the rss data:
using (XmlReader reader = XmlReader.Create(ConfigurationManager.AppSettings["RssFeed"]))
{
SyndicationFeed rssData = SyndicationFeed.Load(reader);
return View(rssData);
}
But where does it go? In the controller for the page that contains the control?
To sum it up, this is how you can do it
[HttpGet, ChildActionOnly]
// put this in RssController
public ActionResult RssFeed()
{
// prepare the model
SyndicationFeed rssData;
using (XmlReader reader = XmlReader.Create(ConfigurationManager.AppSettings["RssFeed"]))
{
rssData = SyndicationFeed.Load(reader);
}
return PartialView(rssData);
}
Usage:
<% Html.RenderAction("RssFeed", "Rss"); %>
And put a check into your ASCX if the Model you are sending in is null and if so, skip everything so it won't render anything. If you leave it like you have it now, it will end in an exception if the Model sent in is null.
Based on my understanding.... Yes, it can go in the controller in the page that contains the control. The partial can use the parent's ViewModel
See here (the bit on Partial Views)
http://msdn.microsoft.com/en-us/library/dd410123.aspx
EDIT
To include your RSS feed
If my controller were named RssController and it had a ViewResult method named RssFeed, I'd include the following on the .Master.
This causes the RssController to get invoked and return the view for your partial (assuming that's what View(rssData) sent back.
In ASP.NET MVC 2+, you can use Html.RenderAction to render an action's result inline.
Giving the action a [ChildActionOnly] attribute will prevent users from navigating to the action normally, making it usable only in this kind of "child" context.
I had a vaguely similar problem (using Razor view engine) which I solved by putting the code into the page since there wasn't anywhere else I wanted to put it. Mine actually related to rendering a menu.
The trick is to use the #functions { ... } construct.
Some pertinent info about the layout stuff here: http://weblogs.asp.net/scottgu/archive/2010/10/22/asp-net-mvc-3-layouts.aspx
Kind of like this in your case (not exactly right; it's late and I'm not on my dev box, but it hopefully gives the idea). That way you don't need any RSS controller at all if you are only doing this small piece of RSS related stuff.
#foreach (var item in RssFeed().Items)
{
<p><a href='#item.Links[0].Uri.OriginalString'><b>#item.Title.Text</b></a></p>
}
#functions {
public SyndicationFeed RssFeed()
{
using (XmlReader reader = XmlReader.Create(ConfigurationManager.AppSettings["RssFeed"]))
{
return SyndicationFeed.Load(reader);
}
}
}
I've began working with asp.net mvc very recently and I've ran into a problem.
I've got an aspx page which renders a few ascx pages. What I'd like to do is declare a global var at the aspx page so it is visible to all its childs. I tried <% var i = 0; %> but it wasn't visible at the child pages.
What could I do?
variables from a aspx page are not shared with the partial views.
The view is just a representation of a piece of data. You have to pass the data as a Model to each view you want to render, whether it's a plain View or a PartialView.
<% Html.RenderPartial("ViewName", Model, ViewDataDictionnary) %>
If you want to pass a variable to a partial view, I would strongly recommend you to add this parameter to the model of the partial view, rather that to pass it additionally via the ViewDataDictionnary.
You can add it to the ViewData and then pass the ViewData to the ascx with
<% Html.RenderPartial("ViewName", Model, ViewData) %>
see msdn on RenderPartial
So in your aspx page you'd do something like
<% ViewData["i"] = 0; %>
And in your userControl you'd just retrive it and use it as you want
<% int i = (int)ViewData["i"] %>
Another way would be to use RenderAction eand pass it as a parameter... so we'd need to know how you display your ascx.
see msdn on RenderAction
How do I create a menu in a ASP.NET MVC2 Master Page, dynamically based on the current user's "role"?
The simplest and most straightforward way would be to simply add an if statement in the view markup:
<% if (Page.User.IsInRole("Admin")) { %>
<%= Html.ActionLink("Admin Tools Index", "Index", "Admin") %>
<%= Html.ActionLink("Admin Dashboard", "Dashboard", "Admin") %>
<% } %>
Or, you can separate out several items pertaining to a specific role into a partial view:
<% if (Page.User.IsInRole("Admin")) { %>
<% Html.RenderPartial("AdminMenu"); %>
<% } %>
I'm not sure about MVC but in 'normal' ASP.NET it is possible to select a MasterPage at runtime.
If you are using the sitemap file to generate menus then you can probably do it in there. If not, then it depends.