This is a migrated thread and some comments may be shown as answers.

An item with the same key has already been added in SitePanelbar.ascx.cs

13 Answers 321 Views
PanelBar
This is a migrated thread and some comments may be shown as answers.
Dan
Top achievements
Rank 2
Dan asked on 31 Oct 2008, 02:57 PM

Hi, we're getting the following error message intermittently - at least several times a day - in the file \Sitefinity\UserControls\Navigation\SitePanelbar.ascx.cs .  We have made a few customizations to the ItemDataBound method in the file, but we can't quite place what might be happening.  Can anyone help us figure out this issue?

Error Message

10/30/2008 1:29:31 PM [UNKNOWN]
************************************************************************************

Exception Type: System.ArgumentException

Message: An item with the same key has already been added.

Source: mscorlib

Stack Trace:
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at Telerik.Cms.Data.CmsPage.get_LanguageVersions()
   at Telerik.Cms.Web.CmsSiteMapProvider.GetChildNodes(SiteMapNode node)
   at System.Web.SiteMapNode.get_ChildNodes()
   at System.Web.UI.WebControls.SiteMapDataSource.GetNodes()
   at System.Web.UI.WebControls.SiteMapDataSource.GetTreeView(String viewPath)
   at System.Web.UI.WebControls.SiteMapDataSource.GetHierarchicalView(String viewPath)
   at System.Web.UI.HierarchicalDataSourceControl.System.Web.UI.IHierarchicalDataSource.GetHierarchicalView(String viewPath)
   at Telerik.RadPanelbarUtils.RadControlDataSource.System.Web.UI.IHierarchicalDataSource.GetHierarchicalView(String viewPath)
   at Telerik.WebControls.RadPanelbar.PerformDataBinding(IEnumerable data)
   at System.Web.UI.WebControls.DataBoundControl.OnDataSourceViewSelectCallback(IEnumerable data)
   at System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback)
   at System.Web.UI.WebControls.DataBoundControl.PerformSelect()
   at System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
   at UserControls_SitemapPanelbar.Page_Load(Object sender, EventArgs e) in d:\share\webroot\cms\Sitefinity\UserControls\Navigation\SitePanelbar.ascx.cs:line 46
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.AddedControl(Control control, Int32 index)
   at System.Web.UI.ControlCollection.Add(Control child)
   at Telerik.Cms.Web.InternalPage.CreateChildControls()
   at System.Web.UI.Control.EnsureChildControls()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
------------------------------------------------------------------------------------

Here's the code for ItemDataBound:

public void RadPanelbar1_ItemDataBound(object sender, RadPanelbarEventArgs e)
    {
        CmsSiteMapNode node = e.Item.DataItem as CmsSiteMapNode;

        if (this.hideUrlForGroupPages)
        {
            if (node != null && node.CmsPage.PageType == CmsPageType.Group)
            {
                e.Item.NavigateUrl = "";
            }
        }
        if (node != null)
        {
            if (node.HasChildNodes)
            {
                e.Item.CssClass = "customFocus";
            }
        }
    }


13 Answers, 1 is accepted

Sort by
0
Georgi
Telerik team
answered on 31 Oct 2008, 03:29 PM
Hello Dan,

Have you tried to change the default language of your web site? Please refer to the Kb Article Changing the default site language to fix your database if this is the case.

Best wishes,
Georgi
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dan
Top achievements
Rank 2
answered on 31 Oct 2008, 06:01 PM
Hi, We haven't tired to change the default language, but this is how its set in our web.config:

<localization defaultProvider="Sitefinity" persistenceMode="QueryString" defaultCulture="en" cultures="en, fr" autoSetClientLanguage="false">
0
Accepted
Georgi
Telerik team
answered on 03 Nov 2008, 01:23 PM
Hello Dan,

In this case, we believe that the problem is related to requests synchronization - two requests occur at the same page at the very same moment. Here's the workaround:

Override the default CmsSiteMapProvider and override GetChildNodes method:

using System.Web; 
using Telerik.Cms.Web; 
 
/// <summary> 
/// Summary description for CmsSiteMapProviderFix 
/// </summary> 
public class CmsSiteMapProviderFix : CmsSiteMapProvider 
    public override SiteMapNodeCollection GetChildNodes(SiteMapNode node) 
    { 
        lock (this
        { 
            return base.GetChildNodes(node); 
        } 
    } 
 

... and change the type of the SiteMapProvider in the web.config:

        <siteMap defaultProvider="CmsSiteMapProvider" enabled="true"
            <providers> 
                <clear/> 
                <add name="CmsSiteMapProvider" description="Displays Cms Pages" type="CmsSiteMapProviderFix"/> 
            </providers> 
        </siteMap> 
 

The bad side of this approach is that it could affect your web site performance a bit.

This problem is fixed in Sitefinity 3.5, and the code is optimized even more, so the performance will not be affected at all. We recommend you to upgrade your project to our latest version.

All the best,
Georgi
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dan
Top achievements
Rank 2
answered on 03 Nov 2008, 07:00 PM
Thanks for the help, Georgi.  We will implement this workaround until we are ready to upgrade.  How much performance degradation can we expect until then, roughly?
0
Georgi
Telerik team
answered on 04 Nov 2008, 09:21 AM
Hi Dan,

This is really hard to tell, because it depends on your web site size (actually, the number of the pages you have - it is directly related to the size of the Sitemap), and of course the server configuration.
The Lock statement will prevent any parallel execution of the surrounded code:
lock (this)  
{  
    return base.GetChildNodes(node);  
}  

Having that said, when there are two requests at the very same time, which need a result from this code, the first one (well, there is always first after all) will lock this code, and the processing will begin. The second one is put on halt (performance hit) and will wait for the first to finish. Once the result is returned, the lock is released and the second locks it again.

Given the fact that the Sitefinity's Sitemap is loaded in the memory most of the time, this should be relatively fast operation. All the code is doing is returning the child elements of a given node. This is for example, returning the names of all sub-pages of a given page.

I don't expect noticeable to the human slowdown, but it all depends on the number of pages you have, number of requests and server load.

In Sitefinity 3.5 SP1 this is solved with using of different kind of caches.

I apologize that could not help you much and could not answer your question completely, but hope that this give you some insight.

All the best,
Georgi
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dan
Top achievements
Rank 2
answered on 04 Nov 2008, 10:07 PM
Thanks for the explanation. Should the slowdown be noticeable if we have the following specs?
  • Windows Server 2003 Ent, SP2
  • 4 x Intel Xeon 3.06GHZ
  • 3.75 GB RAM
  • 1400+ pages in Sitefinity
  • 700,000 hits / day

0
Georgi
Telerik team
answered on 06 Nov 2008, 10:06 AM
Hi Dan,

We do not expect noticeable slowdown with this configuration.

As a side point, we saw that you do not use caching in your web site. The caching will greatly improve your performance. You may refer to the KB article How to optimize the performance of a Sitefinity Web Site for more information.

I think your website would also make great case study. Do you think you could prepare a case study? You have probably checked out the case studies section on the right hand-side of the showcase gallery page but in case you have not you we invite you to. By submitting a case study you would not only contribute to the Sitefinity community and earn Telerik points, but will also gain marketing exposure.

Let us know about your decision.

Regards,
Georgi
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dan
Top achievements
Rank 2
answered on 10 Nov 2008, 04:16 PM
Many thanks for your help on this. I've also marked the answer to the original question in this thread.
As for the caching option, we've disabled caching because keeping it enabled renders our single sign-on solution inoperable -- in the top right-hand area of the page, there should be sign-out / sign-in links along with a personalized link to the account page (which would read, for example, "Dan's Account"); with caching enabled, incorrect information will be displayed in that corner.
As for preparing a case study, I think we could probably do that; I'll discuss it with my team.

One more thing. We've started getting this error again ("item with the same key"), in a different context.  I'm posting the stack trace below; can you help us work out what's happening in this case?  Thanks in advance (again!)

11/7/2008 10:35:49 AM [UNKNOWN]
************************************************************************************

Exception Type: System.ArgumentException

Message: An item with the same key has already been added.

Source: mscorlib

Stack Trace:
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at Telerik.Cms.Data.CmsPage.get_LanguageVersions()
   at Telerik.Cms.Web.CmsSiteMapNode.get_Title()
   at Telerik.Cms.Web.UI.Breadcrumb.InitializeItem(SiteMapNodeItem item)
   at System.Web.UI.WebControls.SiteMapPath.CreateItem(Int32 itemIndex, SiteMapNodeItemType itemType, SiteMapNode node)
   at System.Web.UI.WebControls.SiteMapPath.CreateControlHierarchy()
   at System.Web.UI.WebControls.SiteMapPath.CreateChildControls()
   at System.Web.UI.Control.EnsureChildControls()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
------------------------------------------------------------------------------------

0
Georgi
Telerik team
answered on 13 Nov 2008, 12:07 PM
Hi Dan,

Here's an update of the CmsSiteMapProviderFix have we sent you earlier:
using System.Web;
using Telerik.Cms.Web; 
 
 
public class CmsSiteMapProviderFix : CmsSiteMapProvider  
    public override SiteMapNodeCollection GetChildNodes(SiteMapNode node) 
    { 
        lock (this
        { 
            return base.GetChildNodes(node); 
        } 
    } 
 
    protected override CmsSiteMapNode CreateSiteMapNode(ICmsPage page) 
    { 
        return new CmsSiteMapNodeFix(this, page); 
    } 
 
public class CmsSiteMapNodeFix : CmsSiteMapNode 
    public override string Title 
    { 
        get 
        { 
            lock (this.Provider) 
            { 
                return base.Title; 
            } 
        } 
        set 
        { 
            base.Title = value; 
        } 
    } 

The core of the problem is the same as we already discussed.

Kind regards,
Georgi
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dan
Top achievements
Rank 2
answered on 13 Nov 2008, 04:25 PM

Thanks for the fix!  We updated CmsSiteMapProviderFix and added the Telerik.Cms assembly reference...but now we get the following error:

Server Error in '/' Application.


Compilation Error

Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS1501: No overload for method 'CmsSiteMapNodeFix' takes '2' arguments

Source Error:

Line 21:     {
Line 22: 
Line 23:         return new CmsSiteMapNodeFix(this, page);
Line 24: 
Line 25:     }
0
Accepted
Georgi
Telerik team
answered on 14 Nov 2008, 09:23 AM
Hi Dan,

Ah, yes, the constructor was missing. Here is the code again:
using System.Web; 
using Telerik.Cms.Web; 
using Telerik.Cms; 
 
public class CmsSiteMapProviderFix : CmsSiteMapProvider 
    public override SiteMapNodeCollection GetChildNodes(SiteMapNode node) 
    { 
        lock (this
        { 
            return base.GetChildNodes(node); 
        } 
    } 
 
    protected override CmsSiteMapNode CreateSiteMapNode(ICmsPage page) 
    { 
        return new CmsSiteMapNodeFix(this, page); 
    } 
 
public class CmsSiteMapNodeFix : CmsSiteMapNode 
    public CmsSiteMapNodeFix(CmsSiteMapProvider provider, ICmsPage page) 
        : base(provider, page) 
    {  
    } 
 
    public override string Title 
    { 
        get 
        { 
            lock (this.Provider) 
            { 
                return base.Title; 
            } 
        } 
        set 
        { 
            base.Title = value; 
        } 
    } 
}  
 

I hope everything will be fine this time.

Greetings,
Georgi
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
Dan
Top achievements
Rank 2
answered on 27 Nov 2008, 09:14 PM
Hi Georgi,
Yes, this seems to have solved our problems.  Many thanks for your help in figuring this out.  As for the case study, we'll contact you about it via email.
Thanks
Dan
0
Georgi
Telerik team
answered on 28 Nov 2008, 09:08 AM
Hi Dan,

I am really glad that it did fix the error. I would like to thank you for your cooperation with this issue, and for your decision about the case study.

We will be glad to assist you with anything else, so do not hesitate to contact us again.

Greetings,
Georgi
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Tags
PanelBar
Asked by
Dan
Top achievements
Rank 2
Answers by
Georgi
Telerik team
Dan
Top achievements
Rank 2
Share this question
or