ASP.NET 2.0 menu renders invalid html/css

G

Guest

I have a quite strange problem with the Menu control.

I have ten languages and each language has a SiteMapDataSource and a Menu.
For better performance, I am creating a hashtable (language -> (Menu,
SitemapDataSource)) and holding this hashtable in the Cache object.
On each page request, I am inserting the menu corresponding to the specified
language to page. Hence, DataBinding is only done once per each language
(when inserting the Menu in the hashtable).

This works fine for several page requests. However, after approx. 9 page
requests (for different languages), the menu gets messed.

I have analysed the output of one and the same page for the working and the
not working case. I found out that in the not working case, the code rendered
by the menu control refers styles not declared in that page (styles that are
declared in the working page).

Rendered styles / html in Working case:
=======================================

<style type="text/css">
.SiteMenu4_0 {
background-color:white;visibility:hidden;display:none;position:absolute;left:0px;top:0px; }
.SiteMenu4_1 { text-decoration:none; }
.SiteMenu4_2 { border-style:None; }
.SiteMenu4_3 { border-style:none; }
.SiteMenu4_4 { }
.SiteMenu4_5 { }
.SiteMenu4_6 { border-style:none; }
.SiteMenu4_7 { }
.SiteMenu4_8 { }
.SiteMenu4_9 { border-style:none; }
.SiteMenu4_10 { }
.SiteMenu4_11 { border-style:none; }
.SiteMenu4_12 { }

</style>

html e.g.

<table id="SiteMenu4" class="SiteMenu StaticMenuStyle SiteMenu4_5
SiteMenu4_2" cellpadding="0" cellspacing="0" border="0">
<tr>
<td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)"
onkeyup="Menu_Key(this)" id="SiteMenu4n0"><table class="StaticMenuItemStyle
SiteMenu4_4" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td><a class="SiteMenu4_1 StaticMenuItemStyle SiteMenu4_3" href="#"
style="border-style:none;font-size:1em;cursor:text;">O firmie dummy</a></td>
</tr>
</table>


Rendered styles / html in NOT Working case:
===========================================
<style type="text/css">
.SiteMenu4_26 {
background-color:white;visibility:hidden;display:none;position:absolute;left:0px;top:0px; }
.SiteMenu4_27 { text-decoration:none; }
.SiteMenu4_28 { border-style:None; }
.SiteMenu4_29 { border-style:none; }
.SiteMenu4_30 { }
.SiteMenu4_31 { }
.SiteMenu4_32 { border-style:none; }
.SiteMenu4_33 { }
.SiteMenu4_34 { }
.SiteMenu4_35 { border-style:none; }
.SiteMenu4_36 { }
.SiteMenu4_37 { border-style:none; }
.SiteMenu4_38 { }

</style>

html e.g.

<table id="SiteMenu4" class="SiteMenu StaticMenuStyle SiteMenu4_5
StaticMenuStyle SiteMenu4_5 StaticMenuStyle SiteMenu4_5 SiteMenu4_28"
cellpadding="0" cellspacing="0" border="0">
<tr>
<td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)"
onkeyup="Menu_Key(this)" id="SiteMenu4n0"><table class="StaticMenuItemStyle
SiteMenu4_4" cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td><a class="SiteMenu4_1 StaticMenuItemStyle SiteMenu4_3" href="#"
style="border-style:none;font-size:1em;cursor:text;">O firmie REMS</a></td>
</tr>
</table>



==> As you can see, the class if "SiteMenu4" contains three times
StaticMenuStyle SiteMenu4_5 followed by SiteMenu4_28" .

I expected
SiteMenu4_31 followed by SiteMenu4_28



Any suggestions what is going wrong?
 
S

Steven Cheng[MSFT]

Hi Dpomt,

Welcome.
As for the ASP.NET 2.0 Menu control problem, I'm still having some question
unclear on this:

As you mentioned that you use serveral SiteMapDataSources for each
language's menu, how do you specify them each? ASP.NET 2.0's default
SiteMapProvider only allow single SiteMap file.....

Also, would you provide some further description on the detailed code logic
that you create the menu/hashtable item and bind it to a certain Menu on
the page? If possible, a simplified reproduce page would be much more
helpful ...

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

--------------------
| Thread-Topic: ASP.NET 2.0 menu renders invalid html/css
| thread-index: AcYO6Vp3MvOM+kjeScqvg5J4ElFUNA==
| X-WBNR-Posting-Host: 84.162.109.34
| From: "=?Utf-8?B?ZHBvbXQ=?=" <[email protected]>
| Subject: ASP.NET 2.0 menu renders invalid html/css
| Date: Sun, 1 Jan 2006 07:38:03 -0800
| Lines: 99
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA01.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:367936
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| I have a quite strange problem with the Menu control.
|
| I have ten languages and each language has a SiteMapDataSource and a
Menu.
| For better performance, I am creating a hashtable (language -> (Menu,
| SitemapDataSource)) and holding this hashtable in the Cache object.
| On each page request, I am inserting the menu corresponding to the
specified
| language to page. Hence, DataBinding is only done once per each language
| (when inserting the Menu in the hashtable).
|
| This works fine for several page requests. However, after approx. 9 page
| requests (for different languages), the menu gets messed.
|
| I have analysed the output of one and the same page for the working and
the
| not working case. I found out that in the not working case, the code
rendered
| by the menu control refers styles not declared in that page (styles that
are
| declared in the working page).
|
| Rendered styles / html in Working case:
| =======================================
|
| <style type="text/css">
| .SiteMenu4_0 {
|
background-color:white;visibility:hidden;display:none;position:absolute;left
:0px;top:0px; }
| .SiteMenu4_1 { text-decoration:none; }
| .SiteMenu4_2 { border-style:None; }
| .SiteMenu4_3 { border-style:none; }
| .SiteMenu4_4 { }
| .SiteMenu4_5 { }
| .SiteMenu4_6 { border-style:none; }
| .SiteMenu4_7 { }
| .SiteMenu4_8 { }
| .SiteMenu4_9 { border-style:none; }
| .SiteMenu4_10 { }
| .SiteMenu4_11 { border-style:none; }
| .SiteMenu4_12 { }
|
| </style>
|
| html e.g.
|
| <table id="SiteMenu4" class="SiteMenu StaticMenuStyle SiteMenu4_5
| SiteMenu4_2" cellpadding="0" cellspacing="0" border="0">
| <tr>
| <td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)"
| onkeyup="Menu_Key(this)" id="SiteMenu4n0"><table
class="StaticMenuItemStyle
| SiteMenu4_4" cellpadding="0" cellspacing="0" border="0" width="100%">
| <tr>
| <td><a class="SiteMenu4_1 StaticMenuItemStyle SiteMenu4_3" href="#"
| style="border-style:none;font-size:1em;cursor:text;">O firmie
dummy</a></td>
| </tr>
| </table>
|
|
| Rendered styles / html in NOT Working case:
| ===========================================
| <style type="text/css">
| .SiteMenu4_26 {
|
background-color:white;visibility:hidden;display:none;position:absolute;left
:0px;top:0px; }
| .SiteMenu4_27 { text-decoration:none; }
| .SiteMenu4_28 { border-style:None; }
| .SiteMenu4_29 { border-style:none; }
| .SiteMenu4_30 { }
| .SiteMenu4_31 { }
| .SiteMenu4_32 { border-style:none; }
| .SiteMenu4_33 { }
| .SiteMenu4_34 { }
| .SiteMenu4_35 { border-style:none; }
| .SiteMenu4_36 { }
| .SiteMenu4_37 { border-style:none; }
| .SiteMenu4_38 { }
|
| </style>
|
| html e.g.
|
| <table id="SiteMenu4" class="SiteMenu StaticMenuStyle SiteMenu4_5
| StaticMenuStyle SiteMenu4_5 StaticMenuStyle SiteMenu4_5 SiteMenu4_28"
| cellpadding="0" cellspacing="0" border="0">
| <tr>
| <td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)"
| onkeyup="Menu_Key(this)" id="SiteMenu4n0"><table
class="StaticMenuItemStyle
| SiteMenu4_4" cellpadding="0" cellspacing="0" border="0" width="100%">
| <tr>
| <td><a class="SiteMenu4_1 StaticMenuItemStyle SiteMenu4_3" href="#"
| style="border-style:none;font-size:1em;cursor:text;">O firmie
REMS</a></td>
| </tr>
| </table>
|
|
|
| ==> As you can see, the class if "SiteMenu4" contains three times
| StaticMenuStyle SiteMenu4_5 followed by SiteMenu4_28" .
|
| I expected
| SiteMenu4_31 followed by SiteMenu4_28
|
|
|
| Any suggestions what is going wrong?
|
 
G

Guest

Hello Steven,

thanks for your reply.
As you mentioned that you use serveral SiteMapDataSources for each
language's menu, how do you specify them each? ASP.NET 2.0's default
SiteMapProvider only allow single SiteMap file.....

I have written a custom SiteMapProvider (deriving from SiteMapProvider).
This custom SiteMapProvider retrieves its data from an access database. I
create ten instances of it and pass a language identifier in the constructor.
The implemenation of GetChildNodes takes care about the language of the
current instance.

Also, would you provide some further description on the detailed code logic
that you create the menu/hashtable item and bind it to a certain Menu on
the page?

Ok, I will post you some code with explanation:


class GlobalDataSiteStructure
{
public SortedDictionary<int, SitemapProviderDBEx>
sortedDictLangIDToSiteMapProvider = new SortedDictionary<int,
SitemapProviderDBEx>();
public SortedDictionary<int, KeyValuePair<Menu, SiteMapDataSource>>
sortedDictLangIDToMenuAndSitemapDataSrc = new SortedDictionary<int,
KeyValuePair<Menu, SiteMapDataSource>>();

bool m_bSitemapDataSrcBound = false;

public GlobalDataSiteStructure()
{
Initialize();
}

protected void Initialize()
{

// loop filling sortedDictLangIDToSiteMapProvider
foreach (row in rows)
{
...
sortedDictLangIDToSiteMapProvider.Add(row.LanguageID, new
SitemapProviderDBEx(row.LanguageID));

SiteMapDataSource smdatasrc = new SiteMapDataSource();

smdatasrc.ShowStartingNode = false;
smdatasrc.ID = "smdatasrc";
mdatasrc.Provider = sortedDictLangIDToSiteMapProvider[row.LanguageID];

Menu SiteMenu = new Menu();
SiteMenu.CssClass = "SiteMenu";
SiteMenu.ID = "SiteMenu" + row.LanguageID;

SiteMenu.DataSource = smdatasrc;
}



}

public void MenuDataBind()
{
if (m_bSitemapDataSrcBound)
return;

foreach (KeyValuePair<int, KeyValuePair<Menu, SiteMapDataSource>> kvp in
sortedDictLangIDToMenuAndSitemapDataSrc)
{
Menu SiteMenu = kvp.Value.Key;
SiteMenu.DataBind();
}
m_bSitemapDataSrcBound = true;


}


In my page containing the menu, I create an instance of
GlobalDataSiteStructure, call method MenuDataBind on it and put it in the
cache. Subsequent calls retrieve the GlobalDataSiteStructure instance from
the cache.


....
GlobalDataSiteStructure globalDataSiteStructure =
SiteStructureTools.GetGlobalDataSiteStructureFromCache();
globalDataSiteStructure.MenuDataBind();
Menu SiteMenu =
globalDataSiteStructure.sortedDictLangIDToMenuAndSitemapDataSrc[m_iLanguageID].Key;
HForm.Controls.Add(SiteMenu);
....


public static GlobalDataSiteStructure GetGlobalDataSiteStructureFromCache()
{
HttpContext context = HttpContext.Current;
GlobalDataSiteStructure globalDataSiteStructure =
(GlobalDataSiteStructure)context.Cache.Get("globalDataSiteStructure");
if (globalDataSiteStructure == null)
{
globalDataSiteStructure = new GlobalDataSiteStructure();

HttpContext.Current.Cache.Add("globalDataSiteStructure",
globalDataSiteStructure, null, DateTime.MaxValue, new System.TimeSpan(12, 0,
0), CacheItemPriority.High, null);
}

return globalDataSiteStructure;
}


That's it!

If possible, a simplified reproduce page would be much more
helpful ...

It's quite hard to extract a small sample. If you don't get along with the
provided code and explanations, I will try to make a sample project. Please
let me know.


Best regards,
Dieter
 
S

Steven Cheng[MSFT]

Thanks for your detailed explanation.

So I've basically get your page and code logic on the multi-language menus
and provider system... Though I haven't a concrete page and provider
class to test, what I'm thinking about is whether it'll be better not to
store control instances in Cache (sortedlist...). Generally dynamic
controls are recommended to created in page's life cycle , but not
precreated and cached.... So I think caching the SiteMapProvider instances
are reasonable, but for Menu and SitemapDataSource controls, I suggest you
create them in page everytime....

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)



--------------------
| Thread-Topic: ASP.NET 2.0 menu renders invalid html/css
| thread-index: AcYQrh0pbsZfRPizTS6GE3mZTNd2aw==
| X-WBNR-Posting-Host: 84.162.122.129
| From: "=?Utf-8?B?ZHBvbXQ=?=" <[email protected]>
| References: <[email protected]>
<[email protected]>
| Subject: RE: ASP.NET 2.0 menu renders invalid html/css
| Date: Tue, 3 Jan 2006 13:39:02 -0800
| Lines: 129
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:368379
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Hello Steven,
|
| thanks for your reply.
|
| > As you mentioned that you use serveral SiteMapDataSources for each
| > language's menu, how do you specify them each? ASP.NET 2.0's default
| > SiteMapProvider only allow single SiteMap file.....
|
| I have written a custom SiteMapProvider (deriving from SiteMapProvider).
| This custom SiteMapProvider retrieves its data from an access database. I
| create ten instances of it and pass a language identifier in the
constructor.
| The implemenation of GetChildNodes takes care about the language of the
| current instance.
|
|
| > Also, would you provide some further description on the detailed code
logic
| > that you create the menu/hashtable item and bind it to a certain Menu
on
| > the page?
|
| Ok, I will post you some code with explanation:
|
|
| class GlobalDataSiteStructure
| {
| public SortedDictionary<int, SitemapProviderDBEx>
| sortedDictLangIDToSiteMapProvider = new SortedDictionary<int,
| SitemapProviderDBEx>();
| public SortedDictionary<int, KeyValuePair<Menu, SiteMapDataSource>>
| sortedDictLangIDToMenuAndSitemapDataSrc = new SortedDictionary<int,
| KeyValuePair<Menu, SiteMapDataSource>>();
|
| bool m_bSitemapDataSrcBound = false;
|
| public GlobalDataSiteStructure()
| {
| Initialize();
| }
|
| protected void Initialize()
| {
|
| // loop filling sortedDictLangIDToSiteMapProvider
| foreach (row in rows)
| {
| ...
| sortedDictLangIDToSiteMapProvider.Add(row.LanguageID, new
| SitemapProviderDBEx(row.LanguageID));
|
| SiteMapDataSource smdatasrc = new SiteMapDataSource();

|
| smdatasrc.ShowStartingNode = false;
| smdatasrc.ID = "smdatasrc";
| mdatasrc.Provider =
sortedDictLangIDToSiteMapProvider[row.LanguageID];
|
| Menu SiteMenu = new Menu();
| SiteMenu.CssClass = "SiteMenu";
| SiteMenu.ID = "SiteMenu" + row.LanguageID;
|
| SiteMenu.DataSource = smdatasrc;
| }
|
|
|
| }
|
| public void MenuDataBind()
| {
| if (m_bSitemapDataSrcBound)
| return;
|
| foreach (KeyValuePair<int, KeyValuePair<Menu, SiteMapDataSource>> kvp
in
| sortedDictLangIDToMenuAndSitemapDataSrc)
| {
| Menu SiteMenu = kvp.Value.Key;
| SiteMenu.DataBind();
| }
| m_bSitemapDataSrcBound = true;
|
|
| }
|
|
| In my page containing the menu, I create an instance of
| GlobalDataSiteStructure, call method MenuDataBind on it and put it in the
| cache. Subsequent calls retrieve the GlobalDataSiteStructure instance
from
| the cache.
|
|
| ...
| GlobalDataSiteStructure globalDataSiteStructure =
| SiteStructureTools.GetGlobalDataSiteStructureFromCache();
| globalDataSiteStructure.MenuDataBind();
| Menu SiteMenu =
|
globalDataSiteStructure.sortedDictLangIDToMenuAndSitemapDataSrc[m_iLanguageI
D].Key;
| HForm.Controls.Add(SiteMenu);
| ...
|
|
| public static GlobalDataSiteStructure
GetGlobalDataSiteStructureFromCache()
| {
| HttpContext context = HttpContext.Current;
| GlobalDataSiteStructure globalDataSiteStructure =
| (GlobalDataSiteStructure)context.Cache.Get("globalDataSiteStructure");
| if (globalDataSiteStructure == null)
| {
| globalDataSiteStructure = new GlobalDataSiteStructure();

|
| HttpContext.Current.Cache.Add("globalDataSiteStructure",
| globalDataSiteStructure, null, DateTime.MaxValue, new System.TimeSpan(12,
0,
| 0), CacheItemPriority.High, null);
| }
|
| return globalDataSiteStructure;
| }
|
|
| That's it!
|
|
| >If possible, a simplified reproduce page would be much more
| >helpful ...
|
| It's quite hard to extract a small sample. If you don't get along with
the
| provided code and explanations, I will try to make a sample project.
Please
| let me know.
|
|
| Best regards,
| Dieter
|
 
G

Guest

Thanks for your reply.

Basically, I do not want the menu control retrieves its content each page
request. That's why I have chosen the approach to cache the complete menu.

Do you see any possibilities to further assist me in solving the problem?
Would it help you to get a test project?

Best regards,
Dieter
 
S

Steven Cheng[MSFT]

Not sure whether caching control instances and add them in mulpitple pages
will cause problem, but if convenient, a simple reproduce project (together
with the necessary classes) will be helpful for doing some further test...

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)


--------------------
| Thread-Topic: ASP.NET 2.0 menu renders invalid html/css
| thread-index: AcYSJee/OP5lbCCaSBm9PkqBfyEtFA==
| X-WBNR-Posting-Host: 84.162.92.139
| From: "=?Utf-8?B?ZHBvbXQ=?=" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Subject: RE: ASP.NET 2.0 menu renders invalid html/css
| Date: Thu, 5 Jan 2006 10:29:03 -0800
| Lines: 10
| Message-ID: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="Utf-8"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| Content-Class: urn:content-classes:message
| Importance: normal
| Priority: normal
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Newsgroups: microsoft.public.dotnet.framework.aspnet
| NNTP-Posting-Host: TK2MSFTNGXA03.phx.gbl 10.40.2.250
| Path: TK2MSFTNGXA02.phx.gbl!TK2MSFTNGXA01.phx.gbl!TK2MSFTNGXA03.phx.gbl
| Xref: TK2MSFTNGXA02.phx.gbl
microsoft.public.dotnet.framework.aspnet:368824
| X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
|
| Thanks for your reply.
|
| Basically, I do not want the menu control retrieves its content each page
| request. That's why I have chosen the approach to cache the complete menu.
|
| Do you see any possibilities to further assist me in solving the problem?
| Would it help you to get a test project?
|
| Best regards,
| Dieter
|
 
G

Guest

Steven,

I will try to build a sample project but this might take some time since I
have other issues with the ASP.NET menu control that have higher priority
(see my latest post on this newsgroup).
Will be back as soon as I can provide the testproject.

Best regards,
Dieter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top