Getting this error message when trying to access any page in the site after deploying a new release.
We've added a new property class to the solution and then added that property to a base Page Type.
The property we've added is from SearchEngineSitemaps - http://labs.episerver.com/en/Blogs/Jacob-Khan/Dates/2009/1/Search-Engine-Sitemaps/ (a class called PropertySearchEngineSitemaps)
We didn't add the property to the page through the CMS as we are using PageTypeBuilder to declare the page types in code - http://pagetypebuilder.codeplex.com/
Here is the stack trace. Any ideas?
[UnmappablePropertyTypeException: Unable to map the type for the property SearchEngineSitemaps in BasePage to a suitable EPiServer CMS property.]
PageTypeBuilder.Synchronization.Validation.PageTypeDefinitionPropertiesValidator.ValidatePageTypePropertyType(PropertyInfo propertyInfo) +355
PageTypeBuilder.Synchronization.Validation.PageTypeDefinitionPropertiesValidator.ValidatePageTypeProperties(PageTypeDefinition definition) +125
PageTypeBuilder.Synchronization.Validation.PageTypeDefinitionValidator.ValidatePageTypeDefinitions(List`1 pageTypeDefinitions) +140
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) +0
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean skipVisibilityChecks) +808
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture) +38
System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object providedArgs, ParameterModifier modifiers, CultureInfo culture, String namedParams) +2798
EPiServer.PlugIn.PlugInRuntime.Start(Boolean reset) +633
EPiServer.Web.InitializationModule.Application_BeginRequest(Object sender, EventArgs e) +511
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +171
If we remove the property from the base page type, rebuild, and load a page, we no longer see the error. Interestingly, if we replace the property, then rebuild again, we no longer get the error and our new property is available in Edit mode.
Obviously this isn't a viable solution for a deployment to live - we need it to work first time.
What is happening here? It seems like if you request a page after deploying the new property, and that property has been added to the base page type, then episerver tries to get a property that doesn't exist yet. But if you remove that property from the base page type and rebuild, then reload the page, episerver is able to see that a new property exists and adds it to it's list of property types. Then when you replace the property in the base page type, rebuild, and load a page, episerver now knows this property exists and is able to load the page without error.
Short answer: If you're using EPiServer CMS 5 there's no pretty solution to this. You either have to first add the custom property, compile and start the application (view a page) and then add the property to you page type(s). It's probably possible to do some sort of workaround for this but it won't be pretty. If you on the other hand are using CMS 6 then using the latest version of Page Type Builder, 1.2, should solve this problem.
Long answer: When EPiServer starts up on the first request to the site it looks for any new custom properties in the code. If it finds a new custom property it registers it in the database.
When Page Type Builder starts up, also on the first request, it looks through the code to find new or updated page type classes. If it finds one it will add/update the corresponding page type. In doing so it will add new properties and as part of that it needs to figure out what type the property should be. It does that by first checking the Type property of the PageTypeProperty attribute and secondly, if that isn't specified, it tries to figure out what type it should be based on the (code) property's type. Once it knows the type it needs to retrieve the corresponding PageDefinitionType (EPiServer's class for properties) in order to create a new page type property (a PageDefinition).
In versions of PTB prior to 1.2, that is all versions that target CMS 5, PTB's initialization process happens before EPiServer registers custom properties. This causes PTB to throw an exception once it encounters a property on a page type that there's no matching PageDefinitionType for.
In version 1.2 of PTB which targets CMS 6 it uses the new initilization system in CMS 6 and PTB's initilzation happens after EPiServer registers new properties so there the problem is solved.
If you're using CMS 5 and you really, really, really need to be able to deploy both the custom property and the property on the page type at the same time you could in theory disable PTB's updating of page types and trigger it yourself later on in the site's start up process and I'm sure there are other possible workarounds as well. If you really need it, let me know and I might find some time to look into it. As a general recommendation though, use CMS 6 and PTB 1.2 :)
Firstly, many thanks for your very clear answer to our question.
We figured that the problem was with the sequence of EPi and PTB events and we were about to start looking for a workaround.
It seems though that the best answer would be to upgrade to CMS6 and PTB1.2. We already plan to upgrade to CMS6 soon, and this issue is just one more good reason for us to do so. In the meantime we plan to add any custom properties manually through the GUI (in addition to code) before deploying page types that would use those properties, though we may try your suggestion of disabling PTB's updating. We'll let you know if we need some help :)
Finally, thank you for PTB, which has really helped us to manage our page types on our site. I'm sure my team will echo my gratitude.
Found this thread when I was looking for the same thing.
One fix to this is to change the source to suppress all errors. Then your properties will be created. have done this on a cms 5 site now, and it works. email me @ anders.hattestad at iteraconsulting.no if you want the modifed dll
You also get the same error if you try to have a property of the type PropertyFileUrl, which is an abstract class. This will happend in CMS6 and PTB 1.3.