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

GlassCast Mapping error #189

Closed ChrisWeissRBA closed 8 years ago

ChrisWeissRBA commented 8 years ago

Context: I'm putting together a website using Sitecore 8.1 and Glass.Mapper 4.0.4.53. We're using SimpleInjector for IoC. I've mapped another item without issues before, however it was much simpler than the current item.

Below is where we're seeing the issue. Our GetItem() method is just calling the default Sitecore Database.GetItem method and is correctly returning the right item with the correct values in the fields. It is then given to GlassCast. When this happens, we'll see a couple "'((Castle.Proxies.IHomePageModelProxy)contentResponse.ContentItem).DesiredLink'" errors. (The other properties aren't accessible in debugger)

Outside of debugger, the error that's being returned when a (string) property is accessed is "startIndex cannot be larger than length of string."

(I've changed some names to keep the client's name out of this. I hope I didn't mess up a reference.)

SitecoreContentRepository.cs

public TInterface GetContentItem(string contentGuid) where TInterface : class, IContentBase { Assert.ArgumentNotNullOrEmpty(contentGuid, "contentGuid"); var item = _cmsContext.GetItem(contentGuid); return item != null ? item.GlassCast() : null; }

IHomePageModel.cs

public interface IHomePageModel : IPageBase
{
    Link ContactUsLink { get; }
    Link FacebookLink { get; }
    Link TwitterLink { get; }
    Link LinkedInLink { get; }
    Link YouTubeLink { get; }
    string SearchPlaceholderText { get; }
    Link SearchLink { get; }
    string TopOfPageText { get; }
    Link SiteConfigurationLink { get; }
    Link LeasingPortalLink { get; }
    Link AssociationsLink { get; }
    Link LoginLink { get; }
    Image Logo { get; }
    Link ClientLink { get; }
    string NationalOfficeInfo { get; }
    string LegalLinksInfo { get; }
    string CodeOfEthicsInfo { get; }
    string FarmCreditSystemInfo { get; }
    Image FarmCreditSystemIcon { get; }
    Link SiteMapLink { get; }
    Link FraudAndSecurityCenterLink { get; }
}

HomePageModelMap.cs

public class HomePageModelMap : SitecoreGlassMap<IHomePageModel>
{
    public override void Configure()
    {
        Map(config =>
        {
            ImportMap<IPageBase>();
            config.AutoMap();
            config.Field(f => f.ContactUsLink).FieldName("Contact Us Link");
            config.Field(f => f.FacebookLink).FieldName("Facebook Link");
            config.Field(f => f.TwitterLink).FieldName("Twitter Link");
            config.Field(f => f.LinkedInLink).FieldName("LinkedIn Link");
            config.Field(f => f.YouTubeLink).FieldName("YouTube Link");
            config.Field(f => f.SearchPlaceholderText).FieldName("Search Placeholder Text");
            config.Field(f => f.SearchLink).FieldName("Search Link");
            config.Field(f => f.TopOfPageText).FieldName("Top of Page Text");
            config.Field(f => f.SiteConfigurationLink).FieldName("Site Configuration Link");
            config.Field(f => f.LeasingPortalLink).FieldName("Leasing Portal Link");
            config.Field(f => f.AssociationsLink).FieldName("Associations Link");
            config.Field(f => f.LoginLink).FieldName("Login Link");
            config.Field(f => f.Logo).FieldName("Logo");
            config.Field(f => f.ClientLink).FieldName("Client Link");
            config.Field(f => f.NationalOfficeInfo).FieldName("National Office Info");
            config.Field(f => f.LegalLinksInfo).FieldName("Legal Links Info");
            config.Field(f => f.CodeOfEthicsInfo).FieldName("Code of Ethics Info");
            config.Field(f => f.FarmCreditSystemInfo).FieldName("Farm Credit System Info");
            config.Field(f => f.FarmCreditSystemIcon).FieldName("Farm Credit System Icon");
            config.Field(f => f.SiteMapLink).FieldName("Site Map Link");
            config.Field(f => f.FraudAndSecurityCenterLink).FieldName("Fraud and Security Center Link");
        });
    }
}

Stack Trace for startIndex exception

[ArgumentOutOfRangeException: startIndex cannot be larger than length of string. Parameter name: startIndex] System.String.Substring(Int32 startIndex, Int32 length) +13758496 Sitecore.Links.LinkBuilder.GetItemPathElement(Item item, SiteInfo site) +289 Sitecore.Links.LinkBuilder.BuildItemUrl(Item item) +72 Sitecore.Links.LinkProvider.GetItemUrl(Item item, UrlOptions options) +87 Glass.Mapper.Sc.DataMappers.SitecoreInfoMapper.MapToProperty(AbstractDataMappingContext mappingContext) in c:\TeamCity\buildAgent\work\8567e2ba106d3992\Source\Glass.Mapper.Sc\DataMappers\SitecoreInfoMapper.cs:158 Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateInterface.InterfacePropertyInterceptor.LoadValues() in c:\TeamCity\buildAgent\work\8567e2ba106d3992\Source\Glass.Mapper\Pipelines\ObjectConstruction\Tasks\CreateInterface\InterfacePropertyInterceptor.cs:103 System.Lazy1.CreateValue() +709 System.Lazy1.LazyInitValue() +191 Glass.Mapper.Pipelines.ObjectConstruction.Tasks.CreateInterface.InterfacePropertyInterceptor.Intercept(IInvocation invocation) in c:\TeamCity\buildAgent\work\8567e2ba106d3992\Source\Glass.Mapper\Pipelines\ObjectConstruction\Tasks\CreateInterface\InterfacePropertyInterceptor.cs:65 Castle.DynamicProxy.AbstractInvocation.Proceed() +448 Castle.Proxies.IHomePageModelProxy.get_SearchPlaceholderText() +138 OurSolutionRWD.Web.Controllers.HeaderFooterController.Header() in C:\Projects\OurSolution.com\OurSolutionRWD\OurSolutionRWD.Web\Controllers\HeaderFooterController.cs:52 lambda_method(Closure , ControllerBase , Object[] ) +87 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +229 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +35 System.Web.Mvc.<>cDisplayClass15.b12() +80 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +453 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +453 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +533

mikeedwards83 commented 8 years ago

This is odd because the error is coming from within Sitecore and not Glass. What is the path to the item you are trying to load?

mikeedwards83 commented 8 years ago

Can you supply IPageBase?

ChrisWeissRBA commented 8 years ago

IPageBase.cs

public interface IPageBase : IContentBase
{
    string MetaTitle { get; }
    string MetaDescription { get; }
    string MetaKeywords { get; }
    string NavigationTitle { get; }
    bool IncludeInGlobalNavigation { get; }
    bool ShowBreadcrumbs { get; }
}

IContentBase

public interface IContentBase : ICmsEntity { Guid ID { get; } string Name { get; } string DisplayName { get; } string Path { get; } string Url { get; } string FullPath { get; } string TemplateName { get; } Guid TemplateId { get; } }

ICmsEntity.cs

public interface ICmsEntity
{
}

Just in case...

PageBaseMap.cs

public class PageBaseMap : SitecoreGlassMap<IPageBase>
{
    public override void Configure()
    {
        Map(config =>
        {
            ImportMap<IContentBase>();
            config.AutoMap();
            config.Field(f => f.MetaTitle).FieldName("Meta Title");
            config.Field(f => f.MetaDescription).FieldName("Meta Description");
            config.Field(f => f.MetaKeywords).FieldName("Meta Keywords");
            config.Field(f => f.NavigationTitle).FieldName("Navigation Title");
            config.Field(f => f.IncludeInGlobalNavigation).FieldName("Include In Global Navigation");
            config.Field(f => f.ShowBreadcrumbs).FieldName("Show Breadcrumbs");
        });
    }
}

ContentBaseMap.cs

public class ContentBaseMap : SitecoreGlassMap { public override void Configure() { Map(config => { config.AutoMap(); config.Id(m => m.ID); config.Info(m => m.Name).InfoType(SitecoreInfoType.Name); config.Info(m => m.DisplayName).InfoType(SitecoreInfoType.DisplayName); config.Info(m => m.Path).InfoType(SitecoreInfoType.Path); config.Info(m => m.Url).InfoType(SitecoreInfoType.Url); config.Info(m => m.FullPath).InfoType(SitecoreInfoType.FullPath); config.Info(m => m.TemplateName).InfoType(SitecoreInfoType.TemplateName); config.Info(m => m.TemplateId).InfoType(SitecoreInfoType.TemplateId); }); } }

ChrisWeissRBA commented 8 years ago

Looks like some info got lost in angle brackets for SitecoreContentRepository.cs. Let me try that again.

SitecoreContentRepository.cs

public TInterface GetContentItem< TInterface >(string contentGuid) where TInterface : class, IContentBase { Assert.ArgumentNotNullOrEmpty(contentGuid, "contentGuid"); var item = _cmsContext.GetItem(contentGuid); return item != null ? item.GlassCast< TInterface >() : null; }

ChrisWeissRBA commented 8 years ago

Sorry Mike, here's the path of the item I'm trying to load: /sitecore/content/ClientName/Home

ChrisWeissRBA commented 8 years ago

Running LinkManager.GetItemUrl(item); on the item (below) returned a ArgumentOutOfRangeException. Looks like I got some more digging to do. Thanks everyone!

var item = Sitecore.Context.Database.GetItem(contentGuid);

mikeedwards83 commented 8 years ago

Chris

As this is an issue with Sitecore I am going to close this issue for now. If it turns out that this is a Glass problem please reopen the issue.