baralong
baralong

Reputation: 1713

Glass Mapper (4.1.2.67) failing to map rich text field

I've got a few classes defined to map template items as follows:

public class ContentBase
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    [SitecoreParent]
    public virtual ContentBase Parent { get; set; }
    [SitecoreItem]
    public virtual Item Self { get; set; }
}
[SitecoreType(TemplateId = "{7979766D-DB9C-4E75-9BE3-5B481C6AB6FF}", AutoMap = true)]
public class EventsListing : ContentBase
{
    [SitecoreField(FieldName = "EventsLocation")]
    public virtual SitecoreFolder<Event> Events { get; set; }
}
[SitecoreType(TemplateId = "{CED01C9B-6284-461A-848F-2CDD00CC6DEB}", AutoMap = true)]
public class Event : ContentBase
{
    public virtual string Title { get; set; }
    public virtual string Details { get; set; }
    public virtual string iCalSummary { get; set; }
    public virtual Image ImageLandscape { get; set; }
    public virtual Image ImagePortrait { get; set; }
    public virtual Image ImageSquare { get; set; }
    public virtual string Date { get; set; }
    public virtual DateTime DateStart { get; set; }
    public virtual DateTime DateEnd { get; set; }
    public virtual string Location { get; set; }
    public virtual string GoogleMapsAddress { get; set; }
    public virtual string MemberDiscount { get; set; }
    public virtual Link EventLinkUrl { get; set; }
    public virtual string EventLinkText { get; set; }
}

The template for the Event

The template for the Event

I have a sublayout for the EventsListing based on GlassUserControl and that successfully gets all fields for EventsListing and the children Events. I then have a link on Date to generate an iCal for the Event via a web.api controller

    [RoutePrefix("hbf/api/ical")]
public class EventICalController : ApiController
{
    [Route("{id:guid}")]
    [HttpGet]
    public HttpResponseMessage Get(Guid id)
    {
        var scc = new SitecoreContext(); 
        var item = scc.GetItem<Item>(id);
        var myEvent = scc.GetItem<Models.Event>(id);

The item looks fine and I can access the fields; but the call scc.GetItem(id) throws an exception on the "Details" field.

The exception nesting is (full stack trace below): Glass.Mapper.MapperException "Failed to create type Models.Event" Glass.Mapper.MapperException "Failed to map properties on /sitecore/content/..." Glass.Mapper.MapperException "Failed to map property Details on Models.Event" System.NullReferenceException

If I comment out the "Details" property it works.

I've tried various ways to get the SitecoreContext, even specifying the language to no avail. I've also tried setting the SitecoreField attribute with the name and/or ID and the field type.

What can I in terms of configuration (or something) to resolve this?


{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Failed to create type xxx.Web.Models.Event",
  "ExceptionType": "Glass.Mapper.MapperException",
  "StackTrace": "   at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.CreateObject(ObjectConstructionArgs args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\ObjectConstruction\\Tasks\\CreateConcrete\\CreateConcreteTask.cs:line 115
       at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.Execute(ObjectConstructionArgs args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\ObjectConstruction\\Tasks\\CreateConcrete\\CreateConcreteTask.cs:line 68
       at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 77
       at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
       at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
       at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
       at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
       at Glass.Mapper.Pipelines.AbstractPipelineRunner`2.<>c__DisplayClass3.<CreateTaskExpression>b__2(T args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\AbstractPipelineRunner.cs:line 82
       at Glass.Mapper.AbstractService.InstantiateObject(AbstractTypeCreationContext abstractTypeCreationContext) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\AbstractService.cs:line 138
       at Glass.Mapper.Sc.SitecoreService.CreateType(Type type, Item item, Boolean isLazy, Boolean inferType, Dictionary`2 parameters, Object[] constructorParameters) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper.Sc\\SitecoreService.cs:line 498
       at Glass.Mapper.Sc.SitecoreService.GetItem[T](Guid id, Boolean isLazy, Boolean inferType) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper.Sc\\SitecoreService.cs:line 899
       at xxx.Web.Services.xxx.EventICalController.Get(Guid id) in d:\\Dev\\LW\\xxx.Web\\Services\\xxx\\EventICalController.cs:line 57
       at lambda_method(Closure , Object , Object[] )
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
       at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
        --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
  "InnerException": {
    "Message": "An error has occurred.",
    "ExceptionMessage": "Failed to map properties on /sitecore/content/xxx/Home/Living well/Events/datasources/Health and fitness events/xxx Fitness.",
    "ExceptionType": "Glass.Mapper.MapperException",
    "StackTrace": "   at Glass.Mapper.Configuration.AbstractTypeConfiguration.MapPropertiesToObject(Object obj, IAbstractService service, AbstractTypeCreationContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 174
           at Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateConcrete.CreateConcreteTask.CreateObject(ObjectConstructionArgs args) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Pipelines\\ObjectConstruction\\Tasks\\CreateConcrete\\CreateConcreteTask.cs:line 104",
    "InnerException": {
      "Message": "An error has occurred.",
      "ExceptionMessage": "Failed to map property Details on xxx.Web.Models.Event",
      "ExceptionType": "Glass.Mapper.MapperException",
      "StackTrace": "   at Glass.Mapper.Configuration.AbstractTypeConfiguration.<>c__DisplayClassb.<CreatePropertyExpression>b__a(Object obj, AbstractDataMappingContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 123
           at Glass.Mapper.Configuration.AbstractTypeConfiguration.MapPropertiesToObject(Object obj, IAbstractService service, AbstractTypeCreationContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 144",
      "InnerException": {
        "Message": "An error has occurred.",
        "ExceptionMessage": "Failed to map to property 'Details' on type 'xxx.Web.Models.Event'",
        "ExceptionType": "Glass.Mapper.MapperException",
        "StackTrace": "   at Glass.Mapper.AbstractDataMapper.MapCmsToProperty(AbstractDataMappingContext mappingContext) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\AbstractDataMapper.cs:line 64
               at Glass.Mapper.Configuration.AbstractTypeConfiguration.<>c__DisplayClassb.<CreatePropertyExpression>b__a(Object obj, AbstractDataMappingContext context) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\Configuration\\AbstractTypeConfiguration.cs:line 119",
        "InnerException": {
          "Message": "An error has occurred.",
          "ExceptionMessage": "Object reference not set to an instance of an object.",
          "ExceptionType": "System.NullReferenceException",
          "StackTrace": "   at xxx.Core.Pipelines.RenderField.GetDevModeContent.Process(RenderFieldArgs args)
               at (Object , Object[] )
               at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
               at Glass.Mapper.Sc.DataMappers.SitecoreFieldStringMapper.RunPipeline(Field field) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper.Sc\\DataMappers\\SitecoreFieldStringMapper.cs:line 99
               at Glass.Mapper.AbstractDataMapper.MapCmsToProperty(AbstractDataMappingContext mappingContext) in c:\\TeamCity\\buildAgent\\work\\8567e2ba106d3992\\Source\\Glass.Mapper\\AbstractDataMapper.cs:line 60"
        }
      }
    }
  }
}

Upvotes: 1

Views: 1392

Answers (2)

Amir Setoudeh
Amir Setoudeh

Reputation: 500

I believe that Glass is failing to resolve the Context.Site. Since web api calls don't have a context site by default. You can probably wrap your entire call inside a using (new SiteContextSwitcher(Factory.GetSite("yoursite"))), or find another way to set the Context.Site inside your service call.

or if you have multiple sites, make sure they have the hostName property defined in your <sites> node, and something like this at the top of the call:

var sites = Sitecore.Configuration.Factory.GetSiteInfoList();
string currentHost = HttpContext.Current.Request.Url.Host;
var currentSite = sites.FirstOrDefault(obj => obj.HostName.Equals(currentHost, StringComparison.InvariantCultureIgnoreCase));
if (currentSite != null)
   {
       var newSite = new Sitecore.Sites.SiteContext(currentSite);
       if (newSite != null)
       {                 
           using (new SiteContextSwitcher(newSite))
           {

                ///Code here
           }
       {
    {

Upvotes: 1

baralong
baralong

Reputation: 1713

I added the Glass.Mapper.Sc.* projects source to my solution (yay for open source) and stepped through and found that I needed to add some extra configuration for the rich text field, as follows:

[SitecoreField(Setting = SitecoreFieldSettings.RichTextRaw)]
public virtual string Details { get; set; }

This way the field does not go through the render process and just returns the raw HTML, which is what I wanted. It was the render process that failed, this is kind of a half answer as I don't know why the render process failed, but I don't need it. Unfortunately I didn't find what I needed in the Glass.Mapper documentation.

Upvotes: 2

Related Questions