Description
After upgrading from DNN 10.2.3 to 10.3.0, DDRMenu fails to render with an XmlSerializer error. The menu completely disappears from the site.
Steps to Reproduce
- Have a working DNN 10.2.3 site with DDRMenu using token templates (
.txt files)
- Upgrade to DNN 10.3.0
- Visit any page — the menu is gone
Expected Behavior
Menu renders normally after upgrade.
Actual Behavior
Menu does not render. The following error appears in the DNN Event Log:
Message: Cannot deserialize type 'DotNetNuke.Entities.Users.UserProfile'
because it contains property 'IsDirty' which has no public setter.
StackTrace:
at System.Xml.Serialization.TypeScope.GetSettableMembers(StructMapping mapping, ArrayList list)
at System.Xml.Serialization.TypeScope.GetSettableMembers(StructMapping structMapping)
at System.Xml.Serialization.XmlSerializationReaderILGen.WriteLiteralStructMethod(StructMapping structMapping)
at DotNetNuke.Web.DDRMenu.DNNCommon.Utilities.SerialiserFor(Type t)
at DotNetNuke.Web.DDRMenu.TemplateEngine.TokenTemplateProcessor.Render(
Object source, HtmlTextWriter htmlWriter, TemplateDefinition liveDefinition)
at DotNetNuke.Web.DDRMenu.MenuBase.Render(HtmlTextWriter htmlWriter)
at DotNetNuke.Web.DDRMenu.SkinObject.Render(HtmlTextWriter writer)
Root Cause Analysis
The TokenTemplateProcessor.Render() method in DDRMenu passes a MenuXml object (which includes a UserInfo property) to XmlSerializer. The UserInfo.Profile property is of type UserProfile, which in DNN 10.3.0 has an IsDirty property without a public setter. XmlSerializer requires all public read/write properties to have public setters for deserialization, and throws when encountering IsDirty.
This worked in 10.2.3 because IsDirty either had a public setter or was not a public property.
Workarounds Attempted (none worked)
- Setting
IncludeContext="false" on the <dnn:MENU> skin object
- Reverting to DDRMenu DLL from 10.2.3 (does not help because the
UserProfile class change is in DotNetNuke.dll)
- Reverting to DNN 10.2.3 DLLs — only working solution
Suggested Fix
Either:
- Add
[XmlIgnore] attribute to UserProfile.IsDirty property
- Add a public setter to
UserProfile.IsDirty
- Modify
DDRMenu.DNNCommon.Utilities.SerialiserFor() to use XmlAttributeOverrides to ignore problematic properties
- Modify
TokenTemplateProcessor to not serialize the full UserInfo object when context is not needed
Environment
- DNN Version: 10.3.0 (upgraded from 10.2.3)
- DDRMenu Version: 10.3.0 (also tested with 10.2.3 DLL)
- .NET Framework: 4.8
- Database: SQL Server 2017
- Menu Template: Token-based (.txt), not Razor
Description
After upgrading from DNN 10.2.3 to 10.3.0, DDRMenu fails to render with an XmlSerializer error. The menu completely disappears from the site.
Steps to Reproduce
.txtfiles)Expected Behavior
Menu renders normally after upgrade.
Actual Behavior
Menu does not render. The following error appears in the DNN Event Log:
Root Cause Analysis
The
TokenTemplateProcessor.Render()method in DDRMenu passes aMenuXmlobject (which includes aUserInfoproperty) toXmlSerializer. TheUserInfo.Profileproperty is of typeUserProfile, which in DNN 10.3.0 has anIsDirtyproperty without a public setter.XmlSerializerrequires all public read/write properties to have public setters for deserialization, and throws when encounteringIsDirty.This worked in 10.2.3 because
IsDirtyeither had a public setter or was not a public property.Workarounds Attempted (none worked)
IncludeContext="false"on the<dnn:MENU>skin objectUserProfileclass change is inDotNetNuke.dll)Suggested Fix
Either:
[XmlIgnore]attribute toUserProfile.IsDirtypropertyUserProfile.IsDirtyDDRMenu.DNNCommon.Utilities.SerialiserFor()to useXmlAttributeOverridesto ignore problematic propertiesTokenTemplateProcessorto not serialize the fullUserInfoobject when context is not neededEnvironment