Avatar billede simsen Mester
15. marts 2011 - 00:43 Der er 1 løsning

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;
            }
        }
    }
}
Avatar billede simsen Mester
15. marts 2011 - 10:29 #1
Ja, jeg har så selv fundet fejlen......men fatter nada af det....

Den manglede en connection som jeg har gjort på følgende måde:

DBUtility DAL = new DBUtility();

Når jeg bandt den i codebehind, kunne jeg se, ved at debugge at den gik ind og åbnede (altså connectede) og hentede fra databasen (og det burde den jo i princippet ikke gøre uanset hvad).....

Men gjorde det så ikke, når jeg kørte den af ascx filen med:

<asp:SiteMapDataSource ID="smdsAspNetSqlSiteMapProvider" SiteMapProvider="AspNetSqlSiteMapProvider" runat="server" ShowStartingNode="false" StartingNodeOffset="0" />

Nu mangler jeg så bare at få en parameter med en - vil arbejde lidt videre med den og måske oprette en ny tråd :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester