U4-8043 - 7.4.0 and 7.4.1 - Cannot bind source content type to model content type

Created by Joey Kincer 19 Feb 2016, 21:05:59 Updated by Craig Stevens 09 Aug 2016, 10:12:01

Relates to: U4-8210

Relates to: U4-8406

UPDATE: This has been partially fixed, for more updates, refer to issue U4-8210

This has happened more than once, in a manual clean install of 7.4.0, and also 7.4.1 upgrade (to see if the problem went away).

Nothing complicated with this installation. I have two child doc types (Home, Sub) under a parent doc type (Main). Same hierarchy with the related templates. I only have two published pages at the moment (homepage and subpage). I'll be working around, particularly in the RTE data types and stylesheets, when I randomly start getting this YSOD error message on the website:

Cannot bind source content type Umbraco.Web.PublishedContentModels.Sub (or .Home) to model content type Umbraco.Web.PublishedContentModels.Main

This starts happening on all published pages and doesn't resolve itself, even in preview mode. I'm not sure how it's getting triggered, as I'm not publishing/saving any pages when it happens. But the error doesn't go away unless I do the following steps: comment out all the code in the templates, save, then refresh one of the webpages so it's blank, and then uncomment the code, save, and refresh again and the pages return to normal.

This happened on 7.4.0 first. Tried upgrading to 7.4.1 to see if it went away but it didn't. Finally found the temporary solution after trial/error (although it only lasts for so long before the error randomly returns). Pretty major bug... I wish I knew exactly what the trigger was. I have attached a screenshot with the stack trace in case that helps. If I discover a reproducible path to the error I'll post it here.

3 Attachments

Download models.generated.cs

Download models.generated.cs

Comments

Chriztian Steinmeier 24 Feb 2016, 23:48:17

This just happened to me - here's how to reproduce:

  • Create a Doctype called Blog
  • Create another Doctype called BlogPost
  • Set the template for the BlogPost doctype to the Blog template
  • Create a BlogPost content item and try to Preview it.

This happens because the templates are created with specific (ModelsBuilder?) Models (I think?? @zpqrtbnk ?)

For me, the workaround is to change the 1st line of the Blog template from this:

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.Blog>

to this:

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage


Prashant Tomar 25 Feb 2016, 18:05:36

I tried with @inherits Umbraco.Web.Mvc.UmbracoTemlatePage, but it did not work for me!


Chriztian Steinmeier 25 Feb 2016, 18:55:37

Did you get the same error (assuming UmbracoTemlatePage instead of UmbracoTemplatePage was just a typo in here)?


Michaël Vanbrabandt 01 Mar 2016, 08:53:40

Had the same issue here in umbraco version 7.4.1.

My solution was to edit the web.config file and change:

<add key="Umbraco.ModelsBuilder.ModelsMode" value="PureLive" />

to

<add key="Umbraco.ModelsBuilder.ModelsMode" value="AppData" />

Then in the backend under developer go to the model builder section and generate models. These are now added into the App_data folder.

In visual studio include the App_Data > Models folder, build solution and run.

Error is gone!


Biagio Paruolo 07 Mar 2016, 13:55:51

I've the same problem with 7.4.1. With PureLive active you need to mods config ( add a space ) to compile models.


Biagio Paruolo 09 Mar 2016, 12:56:16

I passed to DLL config.


Daniel Symonds-Lloyd 09 Mar 2016, 13:07:22

Take a look at U4-7754 and the comments. I changed my Layout page to not inherit from ContentModels.Home and the child pages worked.


Douglas Robar 09 Mar 2016, 14:39:21

Another workaround, while leaving PureLive enabled, is to restart the site's application pool. That'll force the models to be rebuilt and clear the error.

Might be nice to have a button to force a rebuild from the Models Builder dashboard in the Developer section of the back office for when you don't have access to the web.config or IIS. Or perhaps there's a way to rebuild without needing to recycle the app pool, which would be better still.


Stephan 15 Mar 2016, 15:59:01

@greystate In your example BlogPost does not inherit from Blog, correct? Then it's normal we cannot map the model for a BlogPost page to a Blog object, and you need to edit the template to either the non-generic UmbracoTemplatePage, or the proper UmbracoTemplatePage.

OTOH in what the original poster describes, Sub ''does'' inherit from ''Main'' (as in, is a child in the doctypes tree) and therefore mapping from a Sub object to a Main object should work. Looking into it.


Stephan 15 Mar 2016, 16:06:34

Note: two errors here. What Doug mentions is, in some cases the models seem to ''not'' update following some changes made on content types. What the original poster describes is, the models ''do'' exist, but suddenly they seem to be re-generated without the proper inheritance.

Note to @kinless : if it happens again, can you capture the content of ~/App_Data/Models/models.generated.cs? Would love to see what's in there.


Chriztian Steinmeier 15 Mar 2016, 16:40:20

@zpqrtbnk Correct - no inheritance. I understand why it happens - it's just a very common pattern for me to have a single template handling both the "list" and "post" views. And all this strongly typed stuff just gets in the way of my workflow :-) I don't need it so I should stop getting the "Document Type" and "Document Type without a Template" options mixed up :)


Joey Kincer 15 Mar 2016, 17:05:19

@zpqrtbnk I have attached the file you requested, although it's with the site working properly. Maybe there's a gremlin hiding in this file that could be helpful to you. I've added more doc types since then so I'd just focus on the Main, Home, and Sub ContentModels.

Haven't run across the error lately as I haven't been fooling around with stylesheets and custom RTE data types (where the error seemed to be triggering). I'll see if I can create some test custom data types to get the error to re-appear. If I do, I'll send you the requested file again.


Stephan 16 Mar 2016, 13:00:50

In that file we see

public partial class FoxxMain : PublishedContentModel

public partial class FoxxSub : FoxxMain

And so mapping from FoxxSub to FoxxMain works because the inheritance is there. In your original description, that mapping fails. Thinking of it, I can see two reasons:

  • The generated models somehow do not have the proper inheritance - but that would be super weird
  • The generated models ''do'' have the proper inheritance - but it's another bug

The "other" bug I'm thinking about is this: models are re-generated but the views are not recompiled, which results in the content cache returning a FoxxSub class which inherits from a FoxxMain class, and the view expects a FoxxMain class too, but ''another'' FoxxMain. It's something that @drobar and @sebastiaan both have reported, and I'm trying to understand what might cause such a situation.


Stephan 16 Mar 2016, 15:48:26

Note to self: thought about a race condition in the PureLive models factory but even putting a proper lock around AddAssemblyReference(_modelsAssembly) does not fix. And, RazorBuildProvider_CodeGenerationStarted is not even reached = the views are ''not'' recompiled. Why?


Joey Kincer 16 Mar 2016, 16:47:06

@zpqrtbnk Good news, I was able to trigger the error again. I simply added a new RTE property to the "Main" doc type and got the binding error.

Funny thing is I downloaded the new models.generated.cs after that happened, but it's exactly the same as the old one I gave you yesterday (yes the file's modification date was changed). So that tells me this file didn't get updated with the new RTE property and it's possibly out of sync(?)

I'll leave my dev site "broken" until I hear further from you if you need any other files or want me to try any procedures. You can PM me if you want to look at the site or need to access the back office.


Stephan 16 Mar 2016, 16:51:02

Ssshhhh... I ''really'' need to find a way to reproduce. So the models.generated.cs file has been touched / re-generated ''but'' without the new property? And then... that mapping error. Ok, still trying to understand what's going on.


Joey Kincer 16 Mar 2016, 17:07:01

@zpqrtbnk Just to make your day more maddening, I did my usual "comment/uncomment templates" trick and then checked the newly-generated models.generated.cs file, and the new property now shows up (and the site works again) so clearly the issue here is that something is out of sync.

Now checking to see if any other properties besides the RTE trigger that bug.


Joey Kincer 16 Mar 2016, 17:25:31

@zpqrtbnk OK now I'm confused. I added a simple Textbox property to the same place in the "Main" doc type, and once again the error was triggered. However the models.generated.cs file showed the new property. I've attached that file, lines 50-57 is where the new prop is. Don't know if it will help.

I think basically to replicate, you just need to have parent/child doc types and parent/child templates in tandem, and just add any property to the parent doc type.

(Apologies to all for the multiple correspondence. I know the team is on deadline to release 7.4.2 very soon so just helping out as best I can.)


Stephan 17 Mar 2016, 12:50:25

Don't apologize - super cool that you help solving this issue. I am now pretty sure this is how it goes: you add the property, models are re-generated in models.generated.cs and re-loaded by the models factory, so the content cache returns a "new" MyContent object, but the views are not recompiled for some reason, and expect the "old" MyContent object.

Now trying to figure out why views are/not recompiled.


Stephan 17 Mar 2016, 13:06:00

Note to self: got a copy of a ASP.NET temporary directory from @sebastiaan while the situation was happening. Shows that all views were compiled at 20:35 (last modified date of eg App_Web_master.cshtml..dll) but the latest App_Web_all.generated.cs..dll and the all.generated.cs..compiled file both have been last modified at 20:38. Which confirms that somehow the views are not being recompiled.


Joey Kincer 17 Mar 2016, 15:50:34

@zpqrtbnk glad you've somewhat narrowed it down. If it helps at all, I found that just touching/saving the "Main" template makes the error go away after it starts happening. So the Views are recompiled when the template is saved, but not when properties are created (at least in my situation).

It also seems to be random, I re-added an existing property and saved the doc type, didn't get the error. However when I removed the property and saved again, then the error re-appeared. The models.generated.cs file doesn't seem to refresh itself until I either reload the website (triggering the error) or touch a template (getting rid of the error).

Good luck in finding the culprit.


Stephan 18 Mar 2016, 15:17:48

Have upgraded ModelsBuilder to 3.0.2 in main dev-v7 branch - ModelsBuilder will now add some extra info to the PureLive assemblies so it's easier to identify them and compare their versions. Then, for Umbraco:

PR https://github.com/umbraco/Umbraco-CMS/pull/1186

This detects when binding from a PureLive type to another PureLive type fails because they come from different assemblies (different version) and automatically force an application restart. Not ideal of course, but at least people will not be stuck anymore not knowing how to get out of the mess.

Review: @sebastiaan knows.


Sebastiaan Janssen 18 Mar 2016, 15:27:32

Merged the PR, it's a good enough workaround for now, but I'll open a new issue to fix this properly.


Sebastiaan Janssen 18 Mar 2016, 15:30:05

New issue: U4-8210


Paul Gower 03 May 2016, 19:28:56

@sebastiaan and @zpqrtbnk The [https://github.com/umbraco/Umbraco-CMS/pull/1186 pull request] you merged in causes an issue if you have the web.config file set to read-only after you install umbraco. The call to the RestartApplicationPool method in the BindModel method is causing a System.UnauthorizedAccessException to be thrown in our production Umbraco installation because we have read-only access setup on the web.config.

169 ApplicationContext.Current.RestartApplicationPool(new HttpContextWrapper(context));

27 File.SetLastWriteTimeUtc(configPath, DateTime.UtcNow);

Should I just set the Umbraco.ModelsBuilder.Enable to false in my web.config so I don't have to enable write access to the web.config on our production server?


Stephan 03 May 2016, 19:57:00

Dammit. We need to fix RestartApplicationPool to unload the app domain and not touch web.config now that we always run with FullTrust! So... if you don't need the models builder then yes you can disable it.

=> issue U4-8405


Paul Gower 03 May 2016, 21:38:25

@zpqrtbnk I'll link my issue I just created to that one you created. Sounds like you'd rather change how RestartApplicationPool works than this pull request.

Also unfortunately we have code that will need to be refactored if we disable models builder so more than likely we will do that once we have time to refactor the views affected. Until then we have enabled modify access on the web.config. =(


Dan Booth 21 May 2016, 19:02:14

I've just encountered this exact error with 7.4.3. However, I'm not using Model Builders; I'm "hand rolling" my own models that inherit from PublishedContentModel and reside in /App_Code/ (though they look pretty similar to the models generated by Model Builders). I found the only way to get rid of the error was to make a code change in one of the model .cs files in /App_Code/ (just add a space, delete and re-save).


Sotiris Filippidis 03 Jul 2016, 19:12:20

I am using AppData with ModelsBuilder, manually copying models from App_Data to App_Code. Upon changing a web.config setting today (set debug to false), I got this error. No other changes were made. I undid the change, but the error still persisted. I completely stopped and then stared the application pool and it went away.


Priority: Major

Type: Bug

State: Fixed

Assignee:

Difficulty: Normal

Category:

Backwards Compatible: True

Fix Submitted:

Affected versions: 7.4.0, 7.4.1, 7.4.3

Due in version: 7.4.2

Sprint: Sprint 11

Story Points:

Cycle: