SQL Site Map Provider virker ikke og ønsker en yderligere parameter med ind
Hej,Jeg forsøger at lave mig en SQL baseret Site Map Provider....Jeg får ingen fejl......men den viser ikke menuen....
Jeg forsøgte så at tilføje den i codebehind filen, for at debugge igennem koden og den virker fint - den laver 36 nodes som den skal (kan jeg se når jeg debugger igennem ssmp.BuildSiteMap()).... Men når jeg forsøger at databind'e den fra codebehind (se kode nederst), så får jeg følgende fejl:
HierarchicalDataBoundControl only accepts data sources that implement IHierarchicalDataSource or IHierarchicalEnumerable.
Og jeg har ikke kunnet finde noget om den fejl, jeg har kunnet forstå.....
Ellers ville jeg jo tilføje den til ascx siden med
<asp:SiteMapDataSource ID="smdsAspNetSqlSiteMapProvider" SiteMapProvider="AspNetSqlSiteMapProvider" runat="server" ShowStartingNode="false" StartingNodeOffset="0" />
Når jeg gør det - får jeg ingen fejl.......men den fremkommer som skrevet heller ikke med menuen.
En anden ting; Jeg vil frygtelig gerne have en værdi mere med ind i WebConfig filen når jeg kalder SiteMapProvideren:
<add name="AspNetSqlSiteMapProvider" etYderligereFelt="ogSåSkriverJegEnVarialHer" description="Default SiteMap Provider" type="SqlSiteMapProvider" securityTrimmingEnabled="true" connectionStringName="AnsiDB"/>
Men gør jeg det, så fik jeg fejl besked om den ikke kendte til etYderligereFelt i SqlSiteMapProvider.
Jeg forsøgte at skrive i SqlSiteMapProvider.cs filen følgende:
// Add a default "countryCode" attribute to countryCode if the
// attribute doesn't exist or is empty
if (string.IsNullOrEmpty(config["countryCode"]))
{
config.Remove("countryCode");
config.Add("countryCode", "en-US");
_countryCode = "en-US";
}
else
{
_countryCode = Convert.ToString(config["countryCode"]);
}
Hvordan skal jeg i stedet gøre?
mvh
simsen
Al min kode til ovennævnte:
ascx filen:
<asp:Menu ID="menuDefault" runat="server"
DynamicHorizontalOffset="0" StaticSubMenuIndent="0px" StaticDisplayLevels="1" Orientation="Horizontal" StaticEnableDefaultPopOutImage="false"
DynamicEnableDefaultPopOutImage="false" CssClass="menuMain" OnMenuItemDataBound="menuDefault_ItemDataBound">
<DataBindings>
<asp:MenuItemBinding DataMember="MenuItem"
NavigateUrlField="NavigateUrl" TextField="textValue" ToolTipField="ToolTip"/>
</DataBindings>
<StaticMenuStyle /> <%--Generelt niveau 1--%>
<DynamicMenuStyle CssClass="dynamicMenu" /> <%--Generelt sub niveauer--%>
<StaticMenuItemStyle CssClass="menuItemStatic" /> <%--Enkelte punkter niveau 1--%>
<DynamicMenuItemStyle CssClass="menuItemDynamic" /> <%--Enkelte punkter sub niveauer--%>
<StaticSelectedStyle /> <%--Valgte punkt på niveau 1--%>
<DynamicSelectedStyle /> <%--Valgte punkt på sub niveauer--%>
<StaticHoverStyle CssClass="staticHover" />
<DynamicHoverStyle CssClass="dynamicHover" />
</asp:Menu>
<%--<asp:SiteMapDataSource ID="smdsAspNetSqlSiteMapProvider" SiteMapProvider="AspNetSqlSiteMapProvider" runat="server" ShowStartingNode="false" StartingNodeOffset="0" />--%>
------------------------------
ascx.cs filen:
if (!IsPostBack)
{
//LoadMenu();
SqlSiteMapProvider ssmp = new SqlSiteMapProvider();
menuDefault.DataSource = ssmp.BuildSiteMap();
menuDefault.DataBind();
}
------------------------------
web.config filen:
<siteMap defaultProvider="AspNetSqlSiteMapProvider" enabled="true">
<providers>
<add name="AspNetSqlSiteMapProvider" etYderligereFelt="ogSåSkriverJegEnVarialHer" description="Default SiteMap Provider" type="SqlSiteMapProvider" securityTrimmingEnabled="true" connectionStringName="AnsiDB"/>
</providers>
</siteMap>
-------------------------------
SqlSiteMapProvider.cs filen (som ligger i App_Code):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
using System.Data.SqlClient;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Provider;
using System.Web.Configuration;
using System.Security.Permissions;
using System.Data.Common;
using System.Data;
using System.Web.Caching;
using AnsiBase.DAL;
using AnsiBase;
/// <summary>
/// Summary description for SqlSiteMapProvider
/// </summary>
[SqlClientPermission(SecurityAction.Demand, Unrestricted = true)]
public class SqlSiteMapProvider : StaticSiteMapProvider
{
private const string _errmsg1 = "Missing node ID";
private const string _errmsg2 = "Duplicate node ID";
private const string _errmsg3 = "Missing parent ID";
private const string _errmsg4 = "Invalid parent ID";
private const string _errmsg5 = "Empty or missing connectionStringName";
private const string _errmsg6 = "Missing connection string";
private const string _errmsg7 = "Empty connection string";
private const string _errmsg8 = "Invalid sqlCacheDependency";
private const string _cacheDependencyName = "__SiteMapCacheDependency";
private AnsiBase.DAL.DBUtility DAL = new AnsiBase.DAL.DBUtility();
public DBUtility.Providers Provider
{
get
{
if (String.IsNullOrEmpty(ConfigurationManager.ConnectionStrings["AnsiDB"].ProviderName.ToString()))
{
if (String.IsNullOrEmpty("SqlServer"))
{
throw new ConfigurationErrorsException("The DBProvider information is missing from the web config file in the appSettings section. Add a providerName entry to the connection string entry to correct this error.");
}
else
{
return (DBUtility.Providers)System.Enum.Parse(typeof(DBUtility.Providers), "SqlServer", true); ;
}
}
else
{
if (String.IsNullOrEmpty(ConfigurationManager.ConnectionStrings["AnsiDB"].ProviderName.ToString()))
{
throw new ConfigurationErrorsException("The providerName information is missing from the web config file on the connection string entry.. Add a providerName entry to the connection string entry to correct this error.");
}
else
{
return (DBUtility.Providers)System.Enum.Parse(typeof(DBUtility.Providers), ConfigurationManager.ConnectionStrings["AnsiDB"].ProviderName.ToString().Trim(), true); ;
}
}
}
}
private string _connect; // Database connection string
private string _database, _table; // Database info for SQL Server 7/2000 cache dependency
private bool _2005dependency = false; // Database info for SQL Server 2005 cache dependency
private Dictionary<int, SiteMapNode> _nodes = new Dictionary<int, SiteMapNode>(16);
private readonly object _lock = new object();
private SiteMapNode _root;
private bool _HasDependency = false; //Bool to use for dependency checks
private string _countryCode;
public override void Initialize(string name, NameValueCollection config)
{
// Verify that config isn't null
if (config == null)
throw new ArgumentNullException("config");
// Assign the provider a default name if it doesn't have one
if (String.IsNullOrEmpty(name))
name = "SqlSiteMapProvider";
// Add a default "description" attribute to config if the
// attribute doesn't exist or is empty
if (string.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "SQL site map provider");
}
// Add a default "countryCode" attribute to countryCode if the
// attribute doesn't exist or is empty
//if (string.IsNullOrEmpty(config["countryCode"]))
//{
// config.Remove("countryCode");
// config.Add("countryCode", "en-US");
// _countryCode = "en-US";
//}
//else
//{
// _countryCode = Convert.ToString(config["countryCode"]);
//}
_countryCode = "en-US";
// Call the base class's Initialize method
base.Initialize(name, config);
// Initialize _connect
string connect = config["connectionStringName"];
if (String.IsNullOrEmpty(connect))
throw new ProviderException(_errmsg5);
config.Remove("connectionStringName");
if (WebConfigurationManager.ConnectionStrings[connect] == null)
throw new ProviderException(_errmsg6);
_connect = WebConfigurationManager.ConnectionStrings[connect].ConnectionString;
if (String.IsNullOrEmpty(_connect))
throw new ProviderException(_errmsg7);
// Initialize SQL cache dependency info
string dependency = config["sqlCacheDependency"];
if (!String.IsNullOrEmpty(dependency))
{
if (String.Equals(dependency, "CommandNotification", StringComparison.InvariantCultureIgnoreCase))
{
SqlDependency.Start(_connect);
_2005dependency = true;
_HasDependency = true;
}
else
{
// If not "CommandNotification", then extract database and table names
string[] info = dependency.Split(new char[] { ':' });
if (info.Length != 2)
throw new ProviderException(_errmsg8);
_database = info[0];
_table = info[1];
_HasDependency = true;
}
config.Remove("sqlCacheDependency");
}
// SiteMapProvider processes the securityTrimmingEnabled
// attribute but fails to remove it. Remove it now so we can
// check for unrecognized configuration attributes.
if (config["securityTrimmingEnabled"] != null)
config.Remove("securityTrimmingEnabled");
// Throw an exception if unrecognized attributes remain
if (config.Count > 0)
{
string attr = config.GetKey(0);
if (!String.IsNullOrEmpty(attr))
throw new ProviderException("Unrecognized attribute: " + attr);
}
}
public override SiteMapNode BuildSiteMap()
{
lock (_lock)
{
if (_root != null)
{
if (_HasDependency)
{
/*
* Return immediately if this method has been called before
* add the provider has the cache dependency flag set.
* Basically the map is cached until a refresh is flagged
* to occur based on the cache engine from the db.
*/
return _root;
}
else
{
/*
* Refresh the site map each time, since there is no
* cache dependency flag set for the provider to use.
* This increases database hits, but ensures the map is
* always updated.
*/
Clear();
_nodes.Clear();
_root = null;
}
}
try
{
DAL.AddParameter("countryCode", "en-US");
DataTable DT = DAL.GetDataTable("GetSiteMap", CommandType.StoredProcedure);
if (DT.Rows.Count > 0)
{
bool isFirst = true;
foreach (DataRow DR in DT.Rows)
{
if (isFirst)
{
// Create the root SiteMapNode and add it to the site map
_root = CreateSiteMapNodeFromDataTable(DR);
AddNode(_root, null);
isFirst = false;
}
else
{
// Build a tree of SiteMapNodes underneath the root node
// Create another site map node and add it to the site map
SiteMapNode node = CreateSiteMapNodeFromDataTable(DR);
AddNode(node, GetParentNodeFromDataTable(DR));
}
}
}
}
catch
{
}
// Return the root SiteMapNode
return _root;
}
}
protected override SiteMapNode GetRootNodeCore()
{
lock (_lock)
{
BuildSiteMap();
return _root;
}
}
private SiteMapNode CreateSiteMapNodeFromDataTable(DataRow DR)
{
// Make sure the node ID is present
if (String.IsNullOrEmpty(DR["ID"].ToString().Trim()))
throw new ProviderException(_errmsg1);
// Get the node ID from the DataReader
int id = Convert.ToInt32(DR["ID"].ToString().Trim());
// Make sure the node ID is unique
if (_nodes.ContainsKey(id))
throw new ProviderException(_errmsg2);
string title = String.Empty;
string url = String.Empty;
string description = String.Empty;
string roles = String.Empty;
if (!String.IsNullOrEmpty(DR["Title"].ToString().Trim()))
{
title = DR["Title"].ToString().Trim();
}
if (!String.IsNullOrEmpty(DR["Url"].ToString().Trim()))
{
url = DR["Url"].ToString().Trim();
}
if (!String.IsNullOrEmpty(DR["Description"].ToString().Trim()))
{
description = DR["Description"].ToString().Trim();
}
if (!String.IsNullOrEmpty(DR["Roles"].ToString().Trim()))
{
roles = DR["Roles"].ToString().Trim();
}
// If roles were specified, turn the list into a string array
string[] rolelist = null;
if (!String.IsNullOrEmpty(roles))
rolelist = roles.Split(new char[] { ',', ';' }, 512);
// Create a SiteMapNode
SiteMapNode node = new SiteMapNode(this, id.ToString(), url, title, description, rolelist, null, null, null);
// Record the node in the _nodes dictionary
_nodes.Add(id, node);
// Return the node
return node;
}
private SiteMapNode GetParentNodeFromDataTable(DataRow DR)
{
// Make sure the parent ID is present
if (String.IsNullOrEmpty(DR["ParentId"].ToString().Trim()))
throw new ProviderException(_errmsg3);
// Get the parent ID from the DataReader
int pid = Convert.ToInt32(DR["ParentId"].ToString().Trim());
// Make sure the parent ID is valid
if (!_nodes.ContainsKey(pid))
throw new ProviderException(_errmsg4);
// Return the parent SiteMapNode
return _nodes[pid];
}
public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
{
//Check to see if the node has roles associated to it. If not allow access to that node
if (node.Roles != null)
{
//Check to see if the user is authenticated. If not do not allow access to a secured node
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
return false;
}
else
{
//Loop through the roles associated to the node and see if the user belongs to any of them
for (int i = 0; i <= node.Roles.Count; i++)
{
//If they are in the role return true
return Roles.IsUserInRole(node.Roles[i].ToString().Trim());
}
return false;
}
}
else
{
return true;
}
}
void OnSiteMapChanged(string key, object item, CacheItemRemovedReason reason)
{
lock (_lock)
{
if (key == _cacheDependencyName && reason == CacheItemRemovedReason.DependencyChanged)
{
// Refresh the site map
Clear();
_nodes.Clear();
_root = null;
}
}
}
}