U4-3485 - Can't use membership provider functions with a membertype that contains a "Belle" property editor

Created by Andrew Swerlick 11 Nov 2013, 20:23:52 Updated by Andrew Swerlick 18 Dec 2013, 04:41:58

I tried to create a custom property editor using the tutorial here http://umbraco.github.io/Belle/#/tutorials/CreatingAPropertyEditor. I was able to get my property editor to work in most scenarios, but found a few scenarios that failed. In particular when I added a datatype using my property editor to a membertype, any functions using the Umbraco Membership Provider failed with the following error

The specified node cannot be inserted as the valid child of this node, because the specified node is the wrong type. at System.Xml.XmlDocument.AppendChildForLoad(XmlNode newChild, XmlDocument doc) at System.Xml.XmlLoader.LoadDocSequence(XmlDocument parentDoc) at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace) at System.Xml.XmlDocument.Load(XmlReader reader) at Umbraco.Core.XmlExtensions.GetXmlNode(XNode element, XmlDocument xmlDoc) in c:\Users\aswerlick\Documents\GitHub\Umbraco-CMS\src\Umbraco.Core\XmlExtensions.cs:line 296 at Umbraco.Core.PropertyEditors.BackwardsCompatibleData.ToXMl(XmlDocument data) in c:\Users\aswerlick\Documents\GitHub\Umbraco-CMS\src\Umbraco.Core\PropertyEditors\BackwardsCompatibleData.cs:line 52 at umbraco.cms.businesslogic.property.Property.ToXml(XmlDocument xd) in c:\Users\aswerlick\Documents\GitHub\Umbraco-CMS\src\umbraco.cms\businesslogic\Property\Property.cs:line 124 at umbraco.cms.businesslogic.Content.XmlPopulate(XmlDocument xd, XmlNode& x, Boolean Deep) in c:\Users\aswerlick\Documents\GitHub\Umbraco-CMS\src\umbraco.cms\businesslogic\Content.cs:line 402 at umbraco.cms.businesslogic.member.Member.generateXmlWithoutSaving(XmlDocument xd) in c:\Users\aswerlick\Documents\GitHub\Umbraco-CMS\src\umbraco.cms\businesslogic\member\Member.cs:line 830 at umbraco.cms.businesslogic.Content.XmlGenerate(XmlDocument xd) in c:\Users\aswerlick\Documents\GitHub\Umbraco-CMS\src\umbraco.cms\businesslogic\Content.cs:line 394 at umbraco.cms.businesslogic.member.Member.Save()

It appears there is an issue with any Belle style property editors and any pieces of the application that use the legacy Member API. To replicate, try the following.

  1. Add the attached editor to the App_Plugins folder
  2. Restart the application
  3. Create a new datatype using the property editor "SimpleEditor"
  4. Add the datatype to any member type
  5. Create a member using that member type
  6. Attempt to change that members password

1 Attachments

Download package.zip

Comments

Andrew Swerlick 11 Nov 2013, 20:25:58

A couple notes on this from my own research. The main issues appear to be in the Umbraco.Core.PropertyEditors.BackwardsCompatibleData class. The first problem is that ln 43 in the ToXMl method, returns an CDATA element, and then tries to add it as a root node of a document, which throws an exception. On top of that, the Value property of the same class always appears to be null.


Shannon Deminick 12 Nov 2013, 04:37:29

Thanks for finding this, investigating now. If a member is already created and you add this property it all works as expected, probably something to do with legacy APIs


Shannon Deminick 12 Nov 2013, 05:08:14

Fixed in e7201b6a69701b7f7157d2fb6212c2709e8ad2e0


Andrew Swerlick 04 Dec 2013, 05:21:20

This may need to be re-opened, or a second related issue opened. While I'm no longer getting the error message, it's not loading the value from the database. Looking Umbraco.Core.PropertyEditors.BackwardsCompatibleData there's no way that the value from the database ever gets loaded. I was able to make things work by copying the lazy loading logic from umbraco.cms.businesslogic.datatype.DefaultData.


Shannon Deminick 04 Dec 2013, 05:27:41

I'll re-open and I'll investigate, IData is obsoleted the 'Data' should get set externally from the loaded database value. Is this happening in the back office or is this happening when you are using some API calls?


Andrew Swerlick 04 Dec 2013, 13:51:04

This is happening when I call ValidateUser from the membership provider. It's blanking out the value from my custom property editor. I'll try to replicate with a simple editor to rule out it's anything on my end.


Andrew Swerlick 04 Dec 2013, 16:24:55

An additional note, I was able to put together a relatively simple workaround. I created the following method which loops through the custom properties, loads their values from the database, and sets the properties on the member class.

internal static void EnsureMemberPropertiesAreLoaded(Member member) { var customProperties = new[] { "distributors"};

        foreach (var customProperty in customProperties)
        {
            if(member.getProperty(customProperty) == null)
                continue;

            var dataPlaceholder = new DefaultData(new DummyDataType());
            dataPlaceholder.Initialize(null, member.getProperty(customProperty).Id);
            member.getProperty(customProperty).Value = dataPlaceholder.Value;
        }
    }

I call this method whenever the Member.BeforeSave method is fired to ensure the member properties are set correctly on save. If others encounter this issue, this should be a good temporary fix.


Shannon Deminick 05 Dec 2013, 05:33:51

This is now all fixed, if you could test that would be really helpful. You can find the final part of the fix in rev: db5b99dbf1da0dd3b9d220429353e9539e0486c7


Andrew Swerlick 18 Dec 2013, 04:41:58

Sorry for the delay, was out of town all last week. I just tested in the 7.0.1 release and this is resolved. Thanks!


Priority: Show-stopper

Type: Bug

State: Fixed

Assignee: Shannon Deminick

Difficulty: Normal

Category: Security

Backwards Compatible: True

Fix Submitted:

Affected versions: 7.0.0

Due in version: 7.0.1

Sprint:

Story Points:

Cycle: