I came across an error the other day working on a menu in the Ektron workarea. When I tried to reorder the menu items for an Italian menu, I got the dreaded “Uh-Ohh…” error page. Reordering the English version of the same menu worked just fine.
Examining the event log on the server revealed these details on the exception:
Exception type: NullReferenceException
Exception message: Object reference not set to an instance of an object.
at Workarea_controls_menu_reordermenuitems.Page_Load(Object sender, EventArgs e) in c:\websites\harkenstage\Workarea\controls\menu\reordermenuitems.ascx.cs:line 77
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Based on this, I opened up the reordermenuitems.ascx.cs file and looked at line 77:
<p> CODE: https://gist.github.com/thec2group-blog/660e5294a8b20250d948b3660f2a3595.js</p>
The culprit was probably one of the two “ToString” method calls, so I looked at where gtNav was defined:
<p> CODE: https://gist.github.com/thec2group-blog/05d27b6abfdfbf6d3d0cc6bd2f1256c5.js</p>
Ok, so where does gtLinks come from?
<p> CODE: https://gist.github.com/thec2group-blog/929b2d192f87cc545ad2deedbb1c69d6.js</p>
Ugh. The dreaded Microsoft.VisualBasic.Collection class. It’s some Frankenstein-ian hybrid between a List and a Dictionary, but, when you run this thing through a JSON-serializer, you get what looks like just a bunch of values with no keys or anything. It’s difficult to figure out what’s going on if you didn’t write the code that constructs the collection in the first place. What I needed was a way to transform a VisualBasic Collection into a Dictionary<string, object>.
I created a test page where I could enter the menu ID (same as this workarea page) and an optional language and it would load the data using the same method as this workarea page. It would then spit out the JSON-formatted data so I could inspect it. The ToDictionary method is adapted from this GitHub gist. I had to make some modifications, because some items don’t have keys in the data being returned from Ektron. I also made it into a recursive function to handle collections within the collection.
<p> CODE: https://gist.github.com/thec2group-blog/cbcedbf8cd1df9db750651327813a8c3.js</p>
One thing stood out when I ran this on the server: the Italian menu had a submenu item that had a null ItemTitle. The English menu had no such null item.
Digging into the database, I found two entries in the menu_to_item_tbl for item_id 83. This was a submenu.
SELECT*frommenu_to_item_tblwhereitem_id= 83
Looking in the menu_tbl, I found menu 83. Problem was, that menu existed only in English, yet the Italian menu somehow had a reference to it.
SELECT*frommenu_tblwheremnu_id= 83
The workarea didn’t show menu 83 as a submenu item in the Italian version, but the link to it still existed in the database, causing the reorder function to fail.
At this point, if you’re following along trying to solve a similar problem on your site, I can’t stress this enough: BACK UP YOUR DATABASE!!!
You’re about to run a delete script. Changing the database is always something that should be done carefully, deliberately, and with lots of backups on hand.
I was able to get things working by running this script:
<p> CODE: https://gist.github.com/thec2group-blog/ee925e6964cc6fad640d273a1301fd6b.js</p>