We've been using uSkinned for a while now and have this recurring problem after we make a deployment. We use WebDeploy to push changes and after each deployment we receive the below error message (can't bind X to X). I understand that the underlying issue is generally something to do with cache and multiple versions of the same class being loaded in, but I have no idea how to solve the issue!
This issue appears to be happening everytime we deploy, regardless of whether the site contains CSS, cshtml or code (compiled DLL) changes. Has anyone come across this before and worked out a solution please?
Umbraco.Web.Mvc.ModelBindingException: Cannot bind source type USNWebsite.USNModels.USNBaseViewModel to model type USNWebsite.USNModels.USNBaseViewModel.
at Umbraco.Web.Mvc.ContentModelBinder.ThrowModelBindingException(Boolean sourceContent, Boolean modelContent, Type sourceType, Type modelType) in D:\a\1\s\src\Umbraco.Web\Mvc\ContentModelBinder.cs:line 159
at Umbraco.Web.Mvc.ContentModelBinder.BindModel(Object source, Type modelType) in D:\a\1\s\src\Umbraco.Web\Mvc\ContentModelBinder.cs:line 66
at Umbraco.Web.Mvc.UmbracoViewPage`1.SetViewData(ViewDataDictionary viewData) in D:\a\1\s\src\Umbraco.Web\Mvc\UmbracoViewPageOfTModel.cs:line 152
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at Umbraco.Web.Mvc.ProfilingView.Render(ViewContext viewContext, TextWriter writer) in D:\a\1\s\src\Umbraco.Web\Mvc\ProfilingView.cs:line 25
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_1.<BeginInvokeAction>b__1(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<>c.<BeginProcessRequest>b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
We got in touch with them a little while back and got the same response - but having to manually recycle an app pool during an automated deployment pipeline doesn’t sit well with me 😂
We have been in touch with Umbraco HQ regarding this issue. This is their unedited response to the problem with a potential solution:
Firstly, I can't see anything wrong with your code - you are following what the documentation indicates and having recreated something analogous to your setup it works as it should. The controller you are creating doesn't have any dependencies, and so the error message isn't referring to an upstream dependency that can't be found - rather it can't resolve the type of the controller itself.
In Umbraco these controllers are registered via scanning the loaded assemblies, finding the controllers and registering them with the IoC container.
So what seems to be happening is some sort of a race condition - at the time of registering controllers, the type isn't found and registered. But you can still set the default render controller to use, and when it tries to find it, it's not registered. There's an issue reported here of something similar - it's been closed, but it's not 100% clear that a resolution was found.
I've not been successful in trying to replicate this problem in a local environment - other than simply using an Umbraco build with the code that does the auto-registration of controllers removed, and confirming I then get the error you are finding.
I have a suggestion though - you could try explicitly registering your controller. You shouldn't have to do this due to the auto-registration, but you can, and it doesn't appear to do any harm to do so (i.e. there's no issue with the controller being registered twice).
I'm thinking this should guarantee the controller is registered before you look to use it, even if - for some reason, and on some occasions - it's been missed by the auto-discovery that Umbraco does.
We are in the process of speaking to Umbraco HQ about this again. Although it is the uSkinned controller that is causing the issue, we are following the recommended approach for overriding the default Umbraco Base Controller.
Thank you for the update and we will update this thread as soon as we have any more information.
Probably easiest to continue discussion here, as I was the person at HQ that had a look at this issue and provided the advice above.
Am a little confused though as the reported error I was asked to look at was:
Message:
An unhandled exception occurred
Exception:
System.Exception: Failed to create an instance of controller type
USNWebsite.USNControllers.USNBaseController (see inner exception). ---> System.InvalidOperationException: Unable to resolve type: USNWebsite.USNControllers.USNBaseController, service name
And so that's what I based the advice on.
But what's reported above around model binding - Cannot bind source type USNWebsite.USNModels.USNBaseViewModel to model type USNWebsite.USNModels.USNBaseViewModel - doesn't immediately seem to be related to this.
Are one of you able to help me understand the connection - or suspected connection - here please?
USNBaseViewModel is created by USNBaseController on startup so I thought that these issues were related.
Cannot bind source type USNWebsite.USNModels.USNBaseViewModel to model type USNWebsite.USNModels.USNBaseViewModel
This error is very strange as its saying it cannot bind a model of same type. The failed to create instance and cannot bind errors both happen on startup and are both solved by restarting the application or restarting the App Pool.
If you need me to send any code over, let me know.
Yes, if you were able to share a stripped down project that either shows the issue - or if it's not easily replicable - what you think would cause this issue, that would be useful if possible.
Slightly different to the stack trace above but we have just received the below on a live site (uSkinned v1.0.3 / Umbraco 8.16). This already has the fix mentioned above to register the controller, but still threw and took over 10 pool recycles to bring it back to life.
Stack trace below:
Exception type: InvalidOperationException
Exception message: Unable to resolve type: USNWebsite.USNControllers.USNBaseController, service name:
at LightInject.ServiceContainer.CreateDelegate(Type serviceType, String serviceName, Boolean throwError) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4754
at LightInject.ServiceContainer.CreateDefaultDelegate(Type serviceType, Boolean throwError) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 4705
at LightInject.ServiceContainer.GetInstance(Type serviceType) in C:\projects\lightinject\src\LightInject\LightInject.cs:line 3437
at Umbraco.Web.Mvc.ContainerControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) in D:\a\1\s\src\Umbraco.Web\Mvc\ContainerControllerFactory.cs:line 21
uSkinned site errors after deployment
Hi!
We've been using uSkinned for a while now and have this recurring problem after we make a deployment. We use WebDeploy to push changes and after each deployment we receive the below error message (can't bind X to X). I understand that the underlying issue is generally something to do with cache and multiple versions of the same class being loaded in, but I have no idea how to solve the issue!
This issue appears to be happening everytime we deploy, regardless of whether the site contains CSS, cshtml or code (compiled DLL) changes. Has anyone come across this before and worked out a solution please?
Thank you, Richard
Hi Richard,
I've seen this happen several times, sometimes after a deployment, but only about 20% of the time, if that.
I've also seen this happen at random sometimes out of normal working hours so have had to setup monitoring with sms messaging when the issue happens.
Sorry I've not got a solution, but confirming you're not the only one with this issue and hoping to hear if there's a solution.
We did contact uskinned and they had seen it before but don't have a solution other than to restart the app pool.
HTH
t
Thanks Tom,
We got in touch with them a little while back and got the same response - but having to manually recycle an app pool during an automated deployment pipeline doesn’t sit well with me 😂
Good to hear we’re not the only ones!
Hi Richard,
We have been in touch with Umbraco HQ regarding this issue. This is their unedited response to the problem with a potential solution:
Firstly, I can't see anything wrong with your code - you are following what the documentation indicates and having recreated something analogous to your setup it works as it should. The controller you are creating doesn't have any dependencies, and so the error message isn't referring to an upstream dependency that can't be found - rather it can't resolve the type of the controller itself.
In Umbraco these controllers are registered via scanning the loaded assemblies, finding the controllers and registering them with the IoC container.
So what seems to be happening is some sort of a race condition - at the time of registering controllers, the type isn't found and registered. But you can still set the default render controller to use, and when it tries to find it, it's not registered. There's an issue reported here of something similar - it's been closed, but it's not 100% clear that a resolution was found.
I've not been successful in trying to replicate this problem in a local environment - other than simply using an Umbraco build with the code that does the auto-registration of controllers removed, and confirming I then get the error you are finding.
I have a suggestion though - you could try explicitly registering your controller. You shouldn't have to do this due to the auto-registration, but you can, and it doesn't appear to do any harm to do so (i.e. there's no issue with the controller being registered twice).
So in your composer, before this line:
Add:
I'm thinking this should guarantee the controller is registered before you look to use it, even if - for some reason, and on some occasions - it's been missed by the auto-discovery that Umbraco does.
The file you want to update is located here:
~/App_Code/USNBusinessLogic/USNUserComposer.cs
Thanks Marc,
That definitely makes sense. We've deployed the fix to one of the sites and recycled it a few times and no error, I'd say that's a win!
#H5YR!
Spoke too soon :(
We've just pushed a change up (after the tests this morning) and the site fell over with the same error as in the original post.
Any further ideas?
Hi Richard,
We are in the process of speaking to Umbraco HQ about this again. Although it is the uSkinned controller that is causing the issue, we are following the recommended approach for overriding the default Umbraco Base Controller.
Thank you for the update and we will update this thread as soon as we have any more information.
Cheers,
Marc
Probably easiest to continue discussion here, as I was the person at HQ that had a look at this issue and provided the advice above.
Am a little confused though as the reported error I was asked to look at was:
And so that's what I based the advice on.
But what's reported above around model binding -
Cannot bind source type USNWebsite.USNModels.USNBaseViewModel to model type USNWebsite.USNModels.USNBaseViewModel
- doesn't immediately seem to be related to this.Are one of you able to help me understand the connection - or suspected connection - here please?
Thanks
Andy
Hi Andy,
USNBaseViewModel is created by USNBaseController on startup so I thought that these issues were related.
Cannot bind source type USNWebsite.USNModels.USNBaseViewModel to model type USNWebsite.USNModels.USNBaseViewModel
This error is very strange as its saying it cannot bind a model of same type. The failed to create instance and cannot bind errors both happen on startup and are both solved by restarting the application or restarting the App Pool.
If you need me to send any code over, let me know.
Thanks for looking into this.
Marc
Yes, if you were able to share a stripped down project that either shows the issue - or if it's not easily replicable - what you think would cause this issue, that would be useful if possible.
Thanks
Andy
Hi Andy,
No problem. Just finishing off for the day so will email you some code in morning.
Cheers,
Marc
Afternoon chaps,
Slightly different to the stack trace above but we have just received the below on a live site (uSkinned v1.0.3 / Umbraco 8.16). This already has the fix mentioned above to register the controller, but still threw and took over 10 pool recycles to bring it back to life.
Stack trace below:
is working on a reply...