How to combine web.sitemap and SiteMapProvider in ASP.NET - asp.net

So, here's what I'm working on. I have an ASP.NET web app, in which the sitemap is displayed on the site.master file through the web.sitemap.
Here's the site.master:
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />
<asp:TreeView
ID="TreeView1"
runat="server"
ataSourceID="SiteMapDataSource1"
ExpandDepth="1">
</asp:TreeView>
And here's the web.sitemap:
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/Default.aspx" title="Home" description="Home">
<siteMapNode url="" title="Projects" description="">
</siteMapNode>
<siteMapNode url="" title="Configurations" description="Configurations">
<siteMapNode url="" title="Experiments" description="Experiments">
</siteMapNode>
<siteMapNode url="" title="Cell Line" description =""></siteMapNode>
<siteMapNode url ="" title ="Drugs">
</siteMapNode>
<siteMapNode url ="" title="Manage Configurations" />
<siteMapNode url="~/ExperimentConfigurationView.aspx" title ="Configure Experiements"/>
<siteMapNode url="~/DrugConfigurationView.aspx" title="Configure Drugs"/>
</siteMapNode>
</siteMapNode>
<siteMapNode url="" title="Drug Recipes" description="">
</siteMapNode>
</siteMapNode>
</siteMap>
Now, here's where I'm running into a problem. What I'd like to do is combine this site map with a dynamically created SiteMapProvider, and populate the sub-trees of this map. For example, the Projects, Experiments, Cell Line and Drug Recipe nodes would each have a sub-tree, populated from a datebase. Anyone have input, or a suggestion as to where to start looking?
In summary - I'd like to point the leaf siteMapNodes to a SiteMapProvider.

Solution:
I added a file DrugListProvider.cs in the root directory. That holds the code for dynamically generating the sub-tree.
I placed the following node in the Web.sitemap, where I wanted the sub-tree to appear:
<siteMapNode provider="DrugListProvider"/>
Finally, I include this in the web.config file:
<siteMap>
<providers>
<add name="DrugListProvider" type="PrivoWeb.DrugListProvider"/>
</providers>
</siteMap>

Related

How can I get my web.sitemap file to work?

Hi, everyone. I have a problem related to my code for an assignment. I am trying to configure my web.sitemap file but I am getting the following when I run my code:
Exactly one element is required directly inside the element.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Configuration.ConfigurationErrorsException: Exactly one element is required directly inside the element.
The siteMapNode for the url="CustomerSupport" is getting an error and it says that: The element 'siteMap' in namespace 'http://schemas.microsoft.com/AspNet/SiteMap-File-1.0' has invalid child element 'siteMapNode' in namespace
I have been stuck with this for a while. I'd really appreciate some help. Here is my code for the we.sitemap file:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Default.aspx" title="Home" description="">
</siteMapNode>
<siteMapNode url="Customer support.aspx" title="Customer support" description="">
<siteMapNode url="ProductRegistration.aspx" title="Register products" description="">
</siteMapNode>
<siteMapNode url="CustomerSurvey.aspx" title="Complete customer survey" description="">
</siteMapNode>
<siteMapNode url="ContactUs.aspx" title="Contact us" description="">
</siteMapNode>
</siteMapNode>
<siteMapNode url="TechnicianSupport.aspx" title="Technician support" description="">
<siteMapNode url="CustomerIncidentDisplay.aspx" title="Display customer incidents" description="">
</siteMapNode>
<siteMapNode url="IncidentUpdate.aspx" title="Update incidents" description="">
</siteMapNode>
</siteMapNode>
<siteMapNode url="Administration.aspx" title="Administration" description="">
<siteMapNode url="ProductMaintenance.aspx" title="Maintain products" description="">
</siteMapNode>
<siteMapNode url="CustomerMaintenance.aspx" title="Maintain customers" description="">
</siteMapNode>
<siteMapNode url="TechnicianMaintenance.aspx" title="Maintain technicians" description="">
</siteMapNode>
<siteMapNode url="IncidentCreation.aspx" title="Create incidents" description="">
</siteMapNode>
<siteMapNode url="TechnicianIncidentSummary.aspx" title="Display techninican incidents" description="">
</siteMapNode>
<siteMapNode url="IncidentAssignment.aspx" title="Assign incidents" description="">
</siteMapNode>
<siteMapNode url="IncidentDisplay.aspx" title="Display incidents" description="">
</siteMapNode>
<siteMapNode url="CustomerDisplay.aspx" title="Display customers" description="">
</siteMapNode>
</siteMapNode>
<siteMapNode url="Map.aspx" title="Site Map" description="">
</siteMapNode>
</siteMap>
You have many nodes where you should only have one:
Inside the main node, put the rest of them.
<siteMapNode name="this is the main node">
<siteMapNode name="1">
<siteMapNode name="11">
</siteMapNode>
<siteMapNode name="12">
</siteMapNode>
</siteMapNode>
<siteMapNode name="2">
</siteMapNode>
<siteMapNode name="3">
</siteMapNode>
</siteMapNode>

.net Menu control SelectedItem always null on homepage

I am using a .net webforms Menu control generated from the following sitemap:
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="NavigationWrapper" description="">
<siteMapNode url="/" title="Home" description="" />
<siteMapNode url="/search" title="Search" description="" />
<siteMapNode url="/contact" title="Contact" description="" />
</siteMapNode>
</siteMap>
When I click the home link, the SelectedItem property of the menu control is always null, but it works fine when clicking the other two links. I can't seem to work out why!
The only way I can seem to get around this is to create a www.abc.com/home link for my homepage, but I'd prefer not to do that.
Any help much appreciated!
Edit:
Route Collection is as follows:
routes.MapPageRoute("Home", "", "~/Default.aspx");
routes.MapPageRoute("Search", "search", "~/SearchByMap.aspx");
routes.MapPageRoute("contact", "contact", "~/Contact.aspx");
Try this:
<siteMapNode url="~/" title="Home" description="">
<siteMapNode url="/search" title="Search" description="" />
<siteMapNode url="/contact" title="Contact" description="" />
</siteMapNode>
Add this to your route collection:
public static void RegisterRoutes(RouteCollection routeCollection)
{
routeCollection.MapPageRoute("Home", "", "~/Default.aspx");
}

The securityTrimmingEnabled="true" in web.config works too good

I'm using C# ASP.NET 4 VS2010.
I'm using membership with roles, which are already defined as usual.
I have a ~/web.sitemap file that includes this:
(The ~/ security is Allow to all.)
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="" description="">
<siteMapNode url="" title="A menu for the Administrator" description="">
<siteMapNode url="~/Admin/ResetPassword.aspx" title="Reset password for a user" description="" />
<siteMapNode url="~/Admin/SendEmailToUser.aspx" title="Send e-mail to a user" description="" />
</siteMapNode>
<siteMapNode url="" title="A menu for the SIC (second in command) person" description="">
<siteMapNode url="~/SIC/UnlockUser.aspx" title="Unlock a user" description="" />
<siteMapNode url="~/SIC/ApproveUser.aspx" title="Approve a user" description="" />
</siteMapNode>
<siteMapNode url="" title="A menu for users" description="">
<siteMapNode url="~/Users/MakeYourContribute.aspx" title="Make your contribution" description="" />
<siteMapNode url="~/Users/CheckOnYourBalance.aspx" title="Check on your balance" description="" />
</siteMapNode>
<siteMapNode url="" title="A menu for anonymous visitors" description="">
<siteMapNode url="~/AboutUs.aspx" title="About us" description="" />
<siteMapNode url="~/Application.aspx" title="Send an application to join us" description="" />
</siteMapNode>
</siteMapNode>
</siteMap>
and a web.config file that ends like this:
<siteMap defaultProvider="XmlSiteMapProvider" enabled ="true">
<providers>
<add name="XmlSiteMapProvider" type="System.Web.XmlSiteMapProvider" siteMapFile="~/web.sitemap" securityTrimmingEnabled="true" />
</providers>
</siteMap>
</system.web>
</configuration>
My menu is based on the asp:Repeater control and looks like this:
<div>
<ul>
<li>
<asp:hyperlink runat="server" id="lnkHome" navigateurl="~/Default.aspx">Home</asp:hyperlink>
</li>
<asp:repeater runat="server" id="menu" datasourceid="SiteMapDataSource1">
<ItemTemplate>
<li>
<asp:HyperLink ID="lnkMenuItem" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
<asp:Repeater ID="submenu" runat="server" DataSource="<%# ((SiteMapNode) Container.DataItem).ChildNodes %>">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink ID="lnkMenuItem" runat="server" NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate> </asp:Repeater> </li> </ItemTemplate> </asp:Repeater> </ul>
<asp:sitemapdatasource id="SiteMapDataSource1" runat="server" showstartingnode="true" />
</div>
The security of allow/deny to folders is defined for the respective folders.
There are 4 levels of security: 1) Administrators. 2)Second In Command (SIC). 3) Users (all registered users). 4) Anonymous users.
For example, both the members of the Administrators role and the SIC role are allowed on the operate in the folder ~/SIC , but the rest of the users are restricted from it.
Now, as soon as I added the securityTrimmingEnabled="true" to the web.config, the only row I see on the menu is Home.
Have I configured anything wrong?
Are there any more configuration I need to make in order to have this security dependent menu work?
The problem is the empty URL in the menu headers.
<siteMapNode url="" title="A menu for the Administrator" description="">
It appears that the sitemap functionality is trying to determine the permissions for the empty url "", and failing.
A workaround is to modify the .sitemap file to explicitly state the roles that can access the parent nodes.
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="" description="" roles="*">
<siteMapNode url="" title="A menu for the Administrator" description="" roles="Administrators">
<siteMapNode url="~/Admin/ResetPassword.aspx" title="Reset password for a user" description="" />
<siteMapNode url="~/Admin/SendEmailToUser.aspx" title="Send e-mail to a user" description="" />
</siteMapNode>
<siteMapNode url="" title="A menu for the SIC (second in command) person" description="" roles="administrators,second in command">
<siteMapNode url="~/SIC/UnlockUser.aspx" title="Unlock a user" description="" />
<siteMapNode url="~/SIC/ApproveUser.aspx" title="Approve a user" description="" />
</siteMapNode>
<siteMapNode url="" title="A menu for users" description="" roles="administrators,secondincommand,users">
<siteMapNode url="~/Users/MakeYourContribute.aspx" title="Make your contribution" description="" />
<siteMapNode url="~/Users/CheckOnYourBalance.aspx" title="Check on your balance" description="" />
</siteMapNode>
<siteMapNode url="" title="A menu for anonymous visitors" description="" roles="*">
<siteMapNode url="~/AboutUs.aspx" title="About us" description="" />
<siteMapNode url="~/Application.aspx" title="Send an application to join us" description="" />
</siteMapNode>
</siteMapNode>
</siteMap>
Admittedly, this isn't ideal, because now you are partially configuring security in two places.
Another option is to just put roles="*" on every menu header. It will still apply the permissions check on every leaf node and hide them if necessary. The downside to this is that it can then display empty menu headers.
Here is the resource which pointed me to this solution: https://web.archive.org/web/20210417091658/http://www.4guysfromrolla.com/articles/122805-1.aspx

TreeView and SiteMap: How to add a line break?

my sitemap is like:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="~/Admin/Default.aspx" title="Administration" description="">
<siteMapNode url="~/Admin/Overview.aspx" title="Übersicht" description="">
<siteMapNode url="~/Admin/UserOverview.aspx" title="Benutzer" description="">
</siteMapNode>
<siteMapNode url="~/Admin/CompanyOverview.aspx" title="Firmen" description="">
</siteMapNode>
<siteMapNode url="~/Admin/OrganisationOverview.aspx" title="Organisationen" description="">
</siteMapNode>
</siteMapNode>
<!-- LINE BREAK SHOULD BE HERE -->
<siteMapNode url="~/Admin/Settings.aspx" title="Einstellungen" description="">
</siteMapNode>
</siteMapNode>
</siteMap>
I have a TreeView binded on it with a SiteMapDataSource.
Here is it how it looks like: http://www.imgimg.de/bild_18a9b0128PNG.png.html
How I get a Linebreak in it?
Taken from this post, you can include the following to get a <hr /> tag but you'll have to disable postback for this item.
<siteMapNode title="<hr />" description="separator" url=""/>

Can I skip nodes in ASP.NET Menu Control?

I have a web.sitemap like this:
<siteMapNode url="~/Default.aspx" title="Home" description="" >
<siteMapNode title="Node 1" description="">
<siteMapNode url="" title="Node 1-1" description="" />
<siteMapNode url="" title="Node 1-2" description="" />
</siteMapNode>
<siteMapNode title="Node 2" description="">
<siteMapNode url="" title="Node 2-1" description="" />
<siteMapNode url="" title="Node 2-2" description="" />
</siteMapNode>
</siteMapNode>
If I use an ASP.NET menu control (with StaticDisplayLevels=2), I get this:
| Home | Node 1 | Node 2 |
Is there a property for skipping "Home" and get this menu (from that sitemap):
| Node 1 | Node 2 |
?
If you are using a SiteMapsDataSource you can skip the root node by setting the ShowStartingNode property to false.
If you aren't already using a SiteMapDataSource to populate the Menu, you can do that and set its ShowStartingNode property to false (and, as noted in the comment above, decrement the StaticDisplayLevels by 1, since you're removing a level) like this:
<asp:SiteMapDataSource ID="MenuSource" runat="server" ShowStartingNode="false" />
Of course, this only works for the root node. To skip other nodes or entire levels of nodes, it would be necessary to massage the source Xml before populating the Menu (for example, use some xslt to strip out a class of nodes).

Resources