mikeedwards83 / Glass.Mapper

Version 5 of the Glass mapping framework, the best ORM for Sitecore.
Apache License 2.0
124 stars 122 forks source link

GetItem not working with abstract model #136

Open tomunderhill opened 9 years ago

tomunderhill commented 9 years ago

I want to do this: SitecoreService.GetItem<MyModel>(id, inferType:true)

where MyModel is an abstract class.

But I get the error pasted below. Making the class non-abstract fixes the issue.

However, I have other models using properties like this, which populate fine even when the model is abstract:

[SitecoreField(Setting = SitecoreFieldSettings.InferType)]
public virtual IEnumerable<MyModel> MyModels { get; set; }

Error:

4460 14:29:50 ERROR Application error.
Exception: System.Web.HttpUnhandledException
Message: An unhandled exception occurred.
Source: Sitecore.Mvc
   at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.ShowErrorMessage(ExceptionContext exceptionContext, ExceptionArgs args)
   at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.Process(ExceptionArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Mvc.Pipelines.PipelineService.RunPipeline[TArgs](String pipelineName, TArgs args)
   at Sitecore.Mvc.Filters.PipelineBasedRequestFilter.OnException(ExceptionContext exceptionContext)
   at System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at Sitecore.Mvc.Controllers.SitecoreActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.<>c__DisplayClass22.<BeginExecuteCore>b__1e()
   at System.Web.Mvc.Async.AsyncResultWrapper.<.cctor>b__0(IAsyncResult asyncResult, Action action)
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at Sitecore.Mvc.Routing.RouteHttpHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Nested Exception

Exception: System.ArgumentNullException
Message: Value cannot be null.
Parameter name: key
Source: mscorlib
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.CreateObject(ObjectConstructionArgs args)
   at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.Execute(ObjectConstructionArgs args)
   at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.Run(T args)
   at Glass.Mapper.AbstractService.InstantiateObject(AbstractTypeCreationContext abstractTypeCreationContext)
   at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.LazyObjectInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.CallToActionModelProxy.get_Id()
   at MyAssembly.CampaignManagerController.<>c__DisplayClass12.<AssignOrRemoveCta>b__e(CallToActionModel x) in c:\Code\MyAssembly\MyAssembly\Controllers\CampaignManagerController.cs:line 191
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
   at MyAssembly.CampaignManagerController.AssignOrRemoveCta(String ids, String ctaId, Boolean remove) in c:\Code\MyAssembly\MyAssembly\Controllers\CampaignManagerController.cs:line 191
   at MyAssembly.CampaignManagerController.AssignCta(String ids, String ctaId) in c:\Code\MyAssembly\MyAssembly\Controllers\CampaignManagerController.cs:line 153
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)

6452 14:29:50 ERROR Application error.
Exception: System.Web.HttpUnhandledException
Message: An unhandled exception occurred.
Source: Sitecore.Mvc
   at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.ShowErrorMessage(ExceptionContext exceptionContext, ExceptionArgs args)
   at Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage.Process(ExceptionArgs args)
   at (Object , Object[] )
   at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
   at Sitecore.Mvc.Pipelines.PipelineService.RunPipeline[TArgs](String pipelineName, TArgs args)
   at Sitecore.Mvc.Filters.PipelineBasedRequestFilter.OnException(ExceptionContext exceptionContext)
   at System.Web.Mvc.ControllerActionInvoker.InvokeExceptionFilters(ControllerContext controllerContext, IList`1 filters, Exception exception)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at Sitecore.Mvc.Controllers.SitecoreActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.<>c__DisplayClass22.<BeginExecuteCore>b__1e()
   at System.Web.Mvc.Async.AsyncResultWrapper.<.cctor>b__0(IAsyncResult asyncResult, Action action)
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at Sitecore.Mvc.Routing.RouteHttpHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Nested Exception

Exception: System.ArgumentNullException
Message: Value cannot be null.
Parameter name: key
Source: mscorlib
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.CreateObject(ObjectConstructionArgs args)
   at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.Execute(ObjectConstructionArgs args)
   at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.Run(T args)
   at Glass.Mapper.AbstractService.InstantiateObject(AbstractTypeCreationContext abstractTypeCreationContext)
   at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.LazyObjectInterceptor.Intercept(IInvocation invocation)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()
   at Castle.Proxies.CallToActionModelProxy.get_Id()
   at MyAssembly.CampaignManagerController.<>c__DisplayClass12.<AssignOrRemoveCta>b__e(CallToActionModel x) in c:\Code\MyAssembly\MyAssembly\Controllers\CampaignManagerController.cs:line 191
   at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate)
   at MyAssembly.CampaignManagerController.AssignOrRemoveCta(String ids, String ctaId, Boolean remove) in c:\Code\MyAssembly\MyAssembly\Controllers\CampaignManagerController.cs:line 191
   at MyAssembly.CampaignManagerController.AssignCta(String ids, String ctaId) in c:\Code\MyAssembly\MyAssembly\Controllers\CampaignManagerController.cs:line 153
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)

Glass version:

 <package id="Glass.Mapper" version="3.0.10.23" targetFramework="net451" />
  <package id="Glass.Mapper.Sc" version="3.2.0.34" targetFramework="net451" />
  <package id="Glass.Mapper.Sc.CastleWindsor" version="3.2.0.17" targetFramework="net451" />
  <package id="Glass.Mapper.Sc.Mvc-5" version="3.2.0.1" targetFramework="net451" />
mikeedwards83 commented 9 years ago

Tom

Glass can't instantiate abstract models. I suspect that the other properties probably work at the moment because when you infer the type it results in a concrete type. At some point I would expect this to break.

We will need to make an enhancement to support inferred types. For the time being you could add a custom task to the object construction pipeline to support abstract types.

Mike