【问题标题】:Glass Mapper (4.1.2.67) failing to map rich text fieldGlass Mapper (4.1.2.67) 无法映射富文本字段
【发布时间】:2016-08-18 07:52:04
【问题描述】:

我定义了一些类来映射模板项,如下所示:

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; }
}

活动模板

我有一个基于 GlassUserControl 的 EventsListing 子布局,它成功获取了 EventsListing 和子事件的所有字段。然后我在 Date 上有一个链接,可以通过 web.api 控制器为事件生成 iCal

    [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);

该项目看起来不错,我可以访问这些字段;但是调用 scc.GetItem(id) 会在“详细信息”字段中引发异常。

异常嵌套是(下面的完整堆栈跟踪): Glass.Mapper.MapperException“未能创建类型 Models.Event” Glass.Mapper.MapperException “无法在 /sitecore/content/... 上映射属性” Glass.Mapper.MapperException“无法在 Models.Event 上映射属性详细信息” System.NullReferenceException

如果我注释掉“详细信息”属性,它会起作用。

我尝试了各种方法来获取 SitecoreContext,即使指定语言也无济于事。我还尝试使用名称和/或 ID 以及字段类型设置 SitecoreField 属性。

我可以在配置(或其他方面)方面如何解决这个问题?


{
  "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"
        }
      }
    }
  }
}

【问题讨论】:

  • 我通常使用 SitecoreService 而不是带有 ApiControllers 的 SitecoreContext。您确定它使用的是正确的数据库吗?
  • 嗯...忽略这个。我错过了您提到您可以获得常规项目并访问字段的部分。您是否配置了任何自定义数据映射器?更完整的堆栈跟踪可能会有所帮助。
  • @BenGolden 添加。我也将尝试获取 GlassMapperSC 的源代码并进入它。
  • 根据您的堆栈跟踪,看起来错误发生在 RenderField 管道的自定义处理器中:xxx.Core.Pipelines.RenderField.GetDevModeContent

标签: sitecore asp.net-web-api2 sitecore7 glass-mapper


【解决方案1】:

我将 Glass.Mapper.Sc.* 项目源添加到我的解决方案中(对开源表示欢迎)并逐步检查并发现我需要添加一些额外的富文本字段的配置,如下:

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

这种方式字段不经过渲染过程,只返回原始 HTML,这正是我想要的。是渲染过程失败了,这是一个半答案,因为我不知道渲染过程为什么失败,但我不需要它。不幸的是,我没有在 Glass.Mapper 文档中找到我需要的内容。

【讨论】:

  • 请注意,如果您使用富文本字段的原始值,您的链接将不会扩展为 SEO/用户友好的 URL。
  • 嗯,这可能是个问题。我会继续挖掘
【解决方案2】:

我认为 Glass 无法解析 Context.Site。由于 web api 调用默认情况下没有上下文站点。您可以将整个调用封装在 using (new SiteContextSwitcher(Factory.GetSite("yoursite"))) 中,或者找到另一种方法在服务调用中设置 Context.Site。

或者,如果您有多个站点,请确保它们在您的 &lt;sites&gt; 节点中定义了 hostName 属性,并且在调用顶部有类似这样的内容:

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
           }
       {
    {

【讨论】:

  • 谢谢你的详细信息,我试过这条线,但我只有一个站点,它仍然没有呈现。我会在下面保留我的修复,但我会继续研究您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
相关资源
最近更新 更多