CodeVerge.Net Beta


   Explore    Item Entry   Register  Login  
Microsoft News
Asp.Net Forums
IBM Software
Borland Forums
Adobe Forums
Novell Forums

MS SQL 2008 on ASP.NET Hosting



Can Reply:  No Members Can Edit: No Online: Yes
Zone: > NEWSGROUP > Asp.Net Forum > general_asp.net.master_pages_themes_and_navigation_controls Tags:
Item Type: NewsGroup Date Entered: 12/27/2005 2:17:39 PM Date Modified: Subscribers: 0 Subscribe Alert
Rate It:
(NR, 0)
XPoints: N/A Replies: 8 Views: 120 Favorited: 0 Favorite
9 Items, 1 Pages 1 |< << Go >> >|
DiCoo
Asp.Net User
Custom sitemapprovider that should get fresh data when parameters changes12/27/2005 2:17:39 PM

0/0

Hi

I have a sitemapprovider that retreives categorydata from a database. The thing is that I need it to retreive data depending on three parameters. One is a querystring parameter and the two other are taken from values stored in cache. But as it is now, I get the same data no matter what. So I guess it get cache somewhere and that ok, untill any of my three parameters get changed then I want it to refresh the data. Or if the querystring parameter is missing it shouldn't show anything.

Maybe a little blury, but I hope you understand and know what I can do about it.

The code is a modified version of Jeff Prosises SqlSiteMapProvider.

public class SqlSiteMapProvider : StaticSiteMapProvider
    {
        static readonly string _errmsg1 = "Missing store ID";
        SiteMapNode _root = null;
        string _connect;

        public override void Initialize(string name, NameValueCollection attributes)
        {
            base.Initialize(name, attributes);

            if (attributes == null)
                throw new ConfigurationErrorsException(_errmsg1);

            _connect = Global.ConnectionString();

        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public override SiteMapNode BuildSiteMap()
        {
            HttpContext context = HttpContext.Current;
            int storeid = Convert.ToInt32(context.Request.QueryString["s"]); //TODO: validation
            int lingo1 = Lingo.GetDefault();
            int lingo2 = Lingo.GetSecondary();

            // Return immediately if this method has been called before
            if (_root != null) return _root;

            // Create a dictionary for temporary node storage and lookup
            Dictionary<int, SiteMapNode> nodes = new Dictionary<int, SiteMapNode>();
           

            // Query the database for site map nodes
            using(SqlConnection connection = new SqlConnection(_connect))
            {
                connection.Open();
               
                SqlCommand command = new SqlCommand("up_CategorySelectByStore", connection);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.Add("@storeid", SqlDbType.Int).Value = storeid;
                command.Parameters.Add("@lingo2", SqlDbType.Int).Value = lingo2;
                command.Parameters.Add("@lingo1", SqlDbType.Int).Value = lingo1;

                SqlDataReader reader = command.ExecuteReader();

                int id = reader.GetOrdinal("Id");
                int parent = reader.GetOrdinal("Parent");
                int url = reader.GetOrdinal("Url");
                int title = reader.GetOrdinal("Title");
                int desc = reader.GetOrdinal("Desc");     

                if (reader.Read())
                {
                    _root = new SiteMapNode(this, "0", "default.aspx", "Root");
                    nodes.Add(0, _root);
                    AddNode(_root, null);

                    while (reader.Read())
                    {
                        SiteMapNode node = new SiteMapNode(this,
                          reader.GetInt32(id).ToString(), reader.GetString(url),
                          reader.GetString(title), reader.IsDBNull(desc) ?
                              "" : reader.GetString(desc));

                        int parentid = reader.IsDBNull(parent) ? 0 : reader.GetInt32(parent);
                        SiteMapNode parentnode = nodes[parentid];

                        nodes.Add(reader.GetInt32(id), node);

                        AddNode(node, parentnode);
                    }
                }
            }
            return _root;
        }

        protected override SiteMapNode GetRootNodeCore()
        {
            BuildSiteMap();
            return _root;
        }
    }


Om du inte f?rst?r vad det st?r h?r s? kan du inte svenska.
DiCoo
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes12/28/2005 12:50:20 PM

0/0

Ok, there were some other threads dealing with the cache thing and a solution was to override the Clear method like below and it seems to work.

protected override void Clear()
{
   base.Clear();
   this._root = null;
}

But I have the problem of when the Clear method should be called. What I need to do is to check if the values from the previous request are the same as the current request. But what/where is the best place to store the values from the previous request?

protected override SiteMapNode GetRootNodeCore()
{
   if (CheckIfSiteMapShouldBeReloaded())
      this.Clear();

   BuildSiteMap();

   return _root;
}

private bool CheckIfSiteMapShouldBeReloaded()
{
   //Check if any of the three parameters are the same on this request

   return true;
}


Om du inte f?rst?r vad det st?r h?r s? kan du inte svenska.
dannychen
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes12/28/2005 5:02:59 PM

0/0

DiCoo,

Please read my additions to this post:  http://forums.asp.net/1152721/ShowPost.aspx .  There will be issues with your current implementation.  I think you should also realize that you're going to have contention if two users hit the site simultaneously that both need the SiteMap rebuilt.  The provider is not a single instance and the data is shared between all sessions. 
--
Danny


disclaimer: Information provided is 'as is' and conveys no warranties or guarantees.
DiCoo
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes12/28/2005 6:12:44 PM

0/0

Thanks for your answer.

I also looked at Dave Sussmans provider that he links to in this thread http://forums.asp.net/971372/ShowPost.aspx. And that code seems to deal with the issues you mention so I will go and rebuild/extend mine on top of that one.

Can also make a request to you Danny or anyone else on the asp.net team. Please build a sitemapprovider that work against a database but have the best-practice of everything in it.

So instead of have to answer the same question about this over and over agian, you will trust me, you can just guide people to the code of that sqlsitemapprovider and everyone can customize that code accoring to the needs they have.


Om du inte f?rst?r vad det st?r h?r s? kan du inte svenska.
DiCoo
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes1/1/2006 6:35:54 PM

0/0

Have now put something together and it looks something like this. My main problem still remains tough. Depending on three parameters so may the SiteMap show/retreive different nodes on each request.

Parameter 1: A querystring. If missing the SiteMap shouldn't show anything.
Parameter 2: A value from cache, different value depending on Parameter 1.
Parameter 3: A value from cache, different value depending on Parameter 1 and a Profile (allowAnonymous="true") value.

If any of these parameters are different from one request to another it should retreive a different set of nodes.

The problem: what the hell am I suppose to do to make this work?

[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
public class SqlSiteMapProvider : StaticSiteMapProvider
{
  
#region Properties
  
private int _lingo1 = 124; // Temp value
  
private int _lingo2 = 56; // Temp value
  
private int _storeid;

   public int StoreId
   {
     
get { return _storeid; }
     
set { _storeid = value; }
   }

   public int Lingo1
   {
     
get { return _lingo1; }
     
set { _lingo1 = value; }
   }

   public int Lingo2
   {
     
get { return _lingo2; }
     
set { _lingo2 = value; }
   }
  
#endregion

   #region Private fields
  
private string _connectionstring;
  
private SiteMapNode _rootnode = null;
  
private Dictionary<int, SiteMapNode> _nodes;
  
private bool _initialized = false;
  
#endregion

   public override void Initialize(string name, NameValueCollection attributes)
   {
     
if(_initialized)
        
return;
  
      base.Initialize(name, attributes);

      _connectionstring = Global.ConnectionString();

      if (String.IsNullOrEmpty(_connectionstring))
        
throw new Exception("The connection string was not found for use in SqlSiteMapProvider.");

      _nodes = new Dictionary<int, SiteMapNode>();

      _initialized = true;
   }

   protected override SiteMapNode GetRootNodeCore()
   {
      BuildSiteMap();
     
return _rootnode;
   }

   protected override void Clear()
   {
     
lock (this)
      {
         _rootnode =
null;
        
base.Clear();
      }
   }

   [MethodImpl(MethodImplOptions.Synchronized)]
   public override SiteMapNode BuildSiteMap()
   {
     
// Since the SiteMap class is static, make sure that it is
     
// not modified while the sitemap is built.
     
lock (this)
     
{
        
// Return immediately if this method has been called before
        
if (_rootnode != null)
           
return _rootnode;

         // Start with a clean slate
        
Clear();

         // Query the database for site map nodes
        
using (SqlConnection connection = new SqlConnection(_connectionstring))
         {
           
SqlCommand command = new SqlCommand("up_CategorySelectByStore", connection);
            command.CommandType =
CommandType.StoredProcedure;
            command.Parameters.Add(
"@storeid", SqlDbType.Int).Value = StoreId;
            command.Parameters.Add(
"@lingo1", SqlDbType.Int).Value = Lingo1;
            command.Parameters.Add(
"@lingo2", SqlDbType.Int).Value = Lingo2;

            connection.Open();

            using (SqlDataReader dr = command.ExecuteReader())
            {
              
int id = dr.GetOrdinal("Id");
              
int parent = dr.GetOrdinal("Parent");
              
int guid = dr.GetOrdinal("Guid");
              
int title = dr.GetOrdinal("Title");
              
int desc = dr.GetOrdinal("Description");

               if (dr.Read())
               {
                  _rootnode =
new SiteMapNode(this, "0", "default.aspx", "Root");
                  _nodes.Add(0, _rootnode);
                  AddNode(_rootnode,
null);
           
                 
while (dr.Read())
                  {
                    
SiteMapNode parentnode = null;
                    
SiteMapNode currentnode = new SiteMapNode(this, dr.GetInt32(id).ToString(), string.Format("~/testmenu.aspx?s={0}&c={1}", StoreId.ToString(), dr.GetString(guid)), dr.GetString(title),dr.IsDBNull(desc) ? "" : dr.GetString(desc));

                     int parentid = dr.IsDBNull(parent) ? 0 : dr.GetInt32(parent);
                     parentnode = _nodes[parentid];
                     _nodes.Add(dr.GetInt32(id), currentnode);

                    AddNode(currentnode, parentnode);
                  }
               }
            }
         }
      }
      return _rootnode;
   }
}


Om du inte f?rst?r vad det st?r h?r s? kan du inte svenska.
dannychen
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes1/3/2006 5:36:06 PM

0/0

DiCoo,

  What you are trying to do is a quite advanced scenario and not easily supported by the out-of-the-box providers.  The StaticSiteMapProvider was designed to store per-application data and you need to store for per-user data.  I think you will find many more difficult issues and bugs to solve with the code you have shown such as concurrency issues and poor performance due to thrashing of your data store with this approach. 
  What you should do is create your own custom SiteMapProvider starting from the SiteMapProvider base.  The biggest issue you need to solve first is how to store the individual users SiteMap data.  One candidate is in session state, another candidate is in application cache.  The next step after you've come up with a storage method for per-user sitemap data is to populate that data.  Most of the BuildSiteMap code you've shown should transfer easily.  Finally, come up with a method that tests whether the data should be rebuilt.  You can add that test to the beginning of BuildSiteMap along side the is rootNode null test.
--
Danny


disclaimer: Information provided is 'as is' and conveys no warranties or guarantees.
DiCoo
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes1/3/2006 10:31:04 PM

0/0

Thanks for your input, its much appreciated.

I got some ideas now on how to make it work (in theory anyway. Smile [:)]) I think the cache can be a good place for storage, just have to move some logic from the database to the code. 
Well, you got me thinking...

Also like to say thank you for your blog post on this subject.


Om du inte f?rst?r vad det st?r h?r s? kan du inte svenska.
DiCoo
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes1/4/2006 11:09:13 AM

0/0

Have started building my provider now but found something that puzzled me. Am looking at three providers to get an idea on how to build mine and saw that all thee have three different object they lock to.
 
SDK documentations Text Site-Map Provider: lock(this)
   (url = http://msdn2.microsoft.com/library/ms178433(en-us,vs.80).aspx)
XmlSiteMapProvider: lock(base._lock)
Dannys blog example: lock(_lockObj)

So whats the difference between them? And which one should be used?


Om du inte f?rst?r vad det st?r h?r s? kan du inte svenska.
dannychen
Asp.Net User
Re: Custom sitemapprovider that should get fresh data when parameters changes1/4/2006 11:20:39 PM

0/0

#2 and #3 are equivelent because the _lock in the base of XmlSiteMapProvider is declared very similarly to how I do it. 

With respect to #1, I don't use this method although in theory it seems like it should work.  I once read an article that had a very compelling reason why lock(this) wasn't a good idea and it stuck.  Unfortunately I don't remember where I read it so I don't have a good reason to offer you.  But now, out of habit, I create a new object instance and use it for my critical sections. 

--
Danny


disclaimer: Information provided is 'as is' and conveys no warranties or guarantees.
9 Items, 1 Pages 1 |< << Go >> >|


Free Download:


Web:
Custom sitemapprovider that should get fresh data when parameters ... Custom sitemapprovider that should get fresh data when parameters changes. Last post 01-04-2006 6:20 PM by dannychen. 8 replies. Sort Posts: ...
Nine ASP.NET Site Navigation Problem Solutions: Part 2 A custom site map provider should implement BuildSiteMap() to return a ... site map information would automatically refresh if the data it displays changes. ...
site navigation Resources | TechRepublic Change default parameters and publish. Open Tag Inspector(F9) and you get full control of ... MSDN Webcast: Creating a Custom SiteMap Provider (Level 200) ...
May 2006 - Posts - Jeffrey Palermo (.com) In my example, I have a custom SiteMapProvider (PageInfoSiteMapProvider). ..... If the test needs data in a database, the setup should insert the required ...
Caching Data with the ObjectDataSource : The Official Microsoft ... But for the majority of applications, caching should be used. For more background on caching in ..... Building a Custom Database-Driven Site Map Provider ...
Sharepoint - Lessons learned We of course should not persist this change since it would ... MasterPageFile = GetMaster(parameter); } } /// /// Get the Master page according to ...
.net and navigation Resources | TechRepublic Change default parameters and publish. Open Tag Inspector(F9) and you get full control of the menu in Dreamweaver. You can easily configure navigation of ...
Introduction to SharePoint Products and Technologies for the ... This capability enables a fresh look at data exposed through SharePoint ... author a custom provider that derives from the SiteMapProvider class to retrieve ...
The Official Microsoft ASP.NET Site But if the cached data never changes, the expiry used by reactive loading is superfluous. ..... Building a Custom Database-Driven Site Map Provider ...
DiscountASP.NET Community Forum help - how to get my site running with dicountasp.net? ... Now (fresh) Error message when trying to view my replacement site: ...




Search This Site:










help! session is no longer working.

splitting up an existing site

"ambiguous match found" error in @page directive

asp.net mobile web application project

publishing web site from command line

aspnet_compiler vs. vs publish for web application projects

why are event handlers wired up in the aspx/ascx page?

constants file in app_globalresources directory changes do not appear without compilation.

create virtual fails if virtual already exists

refresh gridview

ajax enabled web application

asp debugging

vs80-kb915364-x86-enu.exe installtion problem

global.asax issues

links that work in ie does not work in fire fox asp.net 2005

multiple project but one virtual 'root' ... how to navigate between projects?

how to specify custon httphandlers in web.config in vs2005 web app?

vs 2005 s1 & wap compilation issues

mask edit for web forms

website testing tool

adding wap project's "primary output" to web setup project.

wap for dotnetnuke

several problems with asp.net 2.0 web application project

web site project and web application project

app_globalresources

why can't i place my assemblies in a sub-directory of the bin folder?

problem when web app published but ok on asp.net development server

wap and dynamically loaded user controls

wap question

compiling resources into a different file

  Privacy | Contact Us
All Times Are GMT