异常的玻璃在PageEditor模式映射器Sitecore的 [英] Exception in Glass mapper for Sitecore in PageEditor mode

查看:231
本文介绍了异常的玻璃在PageEditor模式映射器Sitecore的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于code:

strMenuText.Append(RenderLink(mainlinkitem,         X => x.NavigationItem.Url.StringToLink(),         isEditable:真正的,         内容:mainlinkitem.NavigationTitle));

下面 mainlinkitem 是数据模板创建界面导航的对象。 我使用的接口,在这种情况下和温莎城堡为此创建动态代理对象。

东西好的工作,直到我尝试使用网页编辑器模式,并提示以下错误:玻璃映射器API显示出来。

  

防爆pression不计算为一个成员   x.NavigationItem.Url.StringToLink()在   Glass.Mapper.Sc.GlassHtml.MakeEditable [T](前pression 1场,   防爆pression 1 standardOutput,T型,字符串参数,上下文   情况下,数据库的数据库,TextWriter的作家)

注:StringToLink是将外部URL中字符串表玻璃映射器扩展方法 Glass.Mapper.Sc.Fields.Link 键入

公共静态链接StringToLink(此字符串urlvalue) {     链接itemLink =新的链接();     itemLink.Url = urlvalue;     返回itemLink; }

更新

$ C $下菜单的用户控件:

公共部分类MenuControl:GlassUserControl< INavigationFolder> {     保护覆盖无效GetModel()     {         base.GetModel();         SiteLevelSettings站点设置= SitecoreContext.GetItem< SiteLevelSettings>(Guid.Parse(有些GUID));         模型= siteSettings.HeaderMenuFolder;     }     保护无效的Page_Load()     {         如果(!Page.IsPostBack)         {             LoadMenu();         }     }     私人无效LoadMenu()     {         StringBuilder的strMenuText =新的StringBuilder();         的foreach(INavigationLink mainlinkitem在Model.ChildLinks)         {             如果(的CanRead(mainlinkitem))             {                 strMenuText.Append(&所述; TD类='菜单项目'>中);                 如果(mainlinkitem.ChildLinks =空&安培;!&安培; mainlinkitem.ChildLinks.Count()大于0)                 {                     strMenuText.Append(&其中; UL>中);                     的foreach(INavigationLink linkitem在mainlinkitem.ChildLinks)                     {                         如果(的CanRead(linkitem))                         {                             strMenuText.Append(<李>);                             如果(linkitem.NavigationItem!= NULL)                             {                                 strMenuText.Append(RenderLink(linkitem,X => x.NavigationItem.Url.StringToLink(),isEditable:假的,内容:linkitem.NavigationTitle));                             }                             否则,如果(linkitem.NavigationGeneralLink!= NULL)                             {                                 strMenuText.Append(RenderLink(linkitem,X => x.NavigationGeneralLink,isEditable:假的,内容:linkitem.NavigationTitle));                             }                             strMenuText.Append(< /李>);                         }                     }                     strMenuText.Append(&所述; / UL>中);                 }                 strMenuText.Append(< D​​IV CLASS ='导航除法>中);                 如果(mainlinkitem.NavigationItem!= NULL)                 {                     strMenuText.Append(RenderLink(mainlinkitem,X => x.NavigationItem.Url.StringToLink(),isEditable:假的,内容:mainlinkitem.NavigationTitle));                 }                 否则,如果(mainlinkitem.NavigationGeneralLink!= NULL)                 {                     strMenuText.Append(RenderLink(mainlinkitem,X => x.NavigationGeneralLink,isEditable:真实,内容:mainlinkitem.NavigationTitle));                 }                 strMenuText.Append(< / DIV>< / TD>中);             }         }         ltrMenu.Text = strMenuText.ToString();     }     私人布尔的CanRead(的iItem mainlinkitem)     {         VAR ITEMID = mainlinkitem.TemplateId;         VAR ItemIDObj =新Sitecore.Data.ID(ITEMID);         VAR contentdatabase = Sitecore.Context.Database;         VAR项目= contentdatabase.GetItem(ItemIDObj);         返回item.Access.CanRead();     } }

玻璃映射器浏览文件夹界面:

[SitecoreType(TemplateId ={有些GUID})] 公共接口INavigationFolder:的iItem {     [SitecoreChildren(IsLazy = FALSE)]     IEnumerable的< INavigationLink> ChildLinks {获得;组; } }

导航链接接口,用于玻璃映射:

[SitecoreType(TemplateId ={有些GUID})] 公共接口INavigationLink:的iItem {     [SitecoreField(FieldId ={有些GUID})]     字符串NavigationTitle {获得;组; }     [SitecoreField(FieldId ={有些GUID})]     的iItem NavigationItem {获得;组; }     [SitecoreField(FieldId ={有些GUID})]     链接NavigationGeneralLink {获得;组; }     [SitecoreField(FieldId ={有些GUID})]     字符串ShortDescription {获得;组; }     [SitecoreChildren(IsLazy = FALSE)]     IEnumerable的< INavigationLink> ChildLinks {获得;组; } }

注意:这将code会生成菜单类似于Sitecore的网站

更新

在接口Url属性的iItem 定义如下:

  [SitecoreType(TemplateId ={有些GUID})]
公共接口的iItem
{
    [SitecoreId()]
    的Guid ID {获得; }

    [SitecoreInfo(类型= SitecoreInfoType.Language)
    语言语言{获得; }

    [SitecoreInfo(类型= SitecoreInfoType.Version)
    诠释版本{获得; }

    [SitecoreInfo(类型= SitecoreInfoType.Url)
    字符串URL {获得; }

    [SitecoreInfo(类型= SitecoreInfoType.TemplateId)
    GUID TemplateId {获得; }

    [SitecoreInfo(类型= SitecoreInfoType.Key)
    字符串键{获得; }
}
 

解决方案

第二EX pression在RenderLink方法应该解决该重新presents在页面编辑器,你想成为可编辑的字段属性,如:

  RenderLink(linkitem,X => x.NavigationItem.Url,isEditable:假的,内容:linkitem.NavigationTitle));
 

当您添加额外的方法调用的前pression结束Glass.Mapper无法评估哪些领域作出正确的编辑。

相反,如果你想要做这样的事情,你应该使用if语句两个效果图之间切换:

 如果(IsInEditingMode)
        {
            strMenuText.Append(RenderLink(
                linkitem,
                X => x.NavigationItem.Url
                isEditable:假的,
                内容:linkitem.NavigationTitle));
        }
        其他
        {
            strMenuText.Append(RenderLink(
                linkitem,
                X => x.NavigationItem.Url.StringToLink(),
                isEditable:假的,
                内容:linkitem.NavigationTitle));
        }
 

不过,我没有测试过这一点,相反,你应该更新你的财产链接字段类型,它会自动将其映射:

  [SitecoreField]
  公共虚拟Glass.Mapper.Sc.Fields.Link网址{获取;集;}
 

您可以再更新菜单code到:

  strMenuText.Append(RenderLink(
                linkitem,
                X => x.NavigationItem.Url
                isEditable:假的,
                内容:linkitem.NavigationTitle));
 

For the code:

strMenuText.Append(RenderLink(mainlinkitem, 
        x => x.NavigationItem.Url.StringToLink(), 
        isEditable: true,            
        contents: mainlinkitem.NavigationTitle));

Here mainlinkitem is Navigation object for interface created for data template. I am using interfaces in this case and castle windsor creates dynamic proxy objects for this.

Things work ok until I try to use Page editor mode and below error shows up from glass mapper api.

Expression doesn't evaluate to a member x.NavigationItem.Url.StringToLink() at Glass.Mapper.Sc.GlassHtml.MakeEditable[T](Expression1 field, Expression1 standardOutput, T model, String parameters, Context context, Database database, TextWriter writer)

Note: StringToLink is extension method for converting external url in string form to Glass mapper Glass.Mapper.Sc.Fields.Link type.

public static Link StringToLink(this string urlvalue)
{
    Link itemLink = new Link();
    itemLink.Url = urlvalue;
    return itemLink;
}

UPDATE

Code for menu user control:

public partial class MenuControl : GlassUserControl<INavigationFolder>
{
    protected override void GetModel()
    {
        base.GetModel();

        SiteLevelSettings siteSettings = SitecoreContext.GetItem<SiteLevelSettings>(Guid.Parse("Some GUID"));
        Model = siteSettings.HeaderMenuFolder;
    }

    protected void Page_Load()
    {
        if (!Page.IsPostBack)
        {
            LoadMenu();
        }
    }

    private void LoadMenu()
    {
        StringBuilder strMenuText = new StringBuilder();

        foreach (INavigationLink mainlinkitem in Model.ChildLinks)
        {
            if (CanRead(mainlinkitem))
            {
                strMenuText.Append("<td class='menu-item'>");
                if (mainlinkitem.ChildLinks != null && mainlinkitem.ChildLinks.Count() > 0)
                {
                    strMenuText.Append("<ul>");
                    foreach (INavigationLink linkitem in mainlinkitem.ChildLinks)
                    {
                        if (CanRead(linkitem))
                        {
                            strMenuText.Append("<li>");
                            if (linkitem.NavigationItem != null)
                            {
                                strMenuText.Append(RenderLink(linkitem, x => x.NavigationItem.Url.StringToLink(), isEditable: false, contents: linkitem.NavigationTitle));
                            }
                            else if (linkitem.NavigationGeneralLink != null)
                            {
                                strMenuText.Append(RenderLink(linkitem, x => x.NavigationGeneralLink, isEditable: false, contents: linkitem.NavigationTitle));
                            }
                            strMenuText.Append("</li>");
                        }
                    }

                    strMenuText.Append("</ul>");
                }
                strMenuText.Append("<div class='nav-divider'>");
                if (mainlinkitem.NavigationItem != null)
                {
                    strMenuText.Append(RenderLink(mainlinkitem, x => x.NavigationItem.Url.StringToLink(), isEditable: false, contents: mainlinkitem.NavigationTitle));
                }
                else if (mainlinkitem.NavigationGeneralLink != null)
                {
                    strMenuText.Append(RenderLink(mainlinkitem, x => x.NavigationGeneralLink, isEditable: true, contents: mainlinkitem.NavigationTitle));
                }
                strMenuText.Append("</div></td>");
            }
        }

        ltrMenu.Text = strMenuText.ToString();
    }

    private bool CanRead(IItem mainlinkitem)
    {
        var ItemId = mainlinkitem.TemplateId;
        var ItemIDObj = new Sitecore.Data.ID(ItemId);
        var contentdatabase = Sitecore.Context.Database;
        var item = contentdatabase.GetItem(ItemIDObj);
        return item.Access.CanRead();
    }
}

Navigation Folder interface for glass mapper:

[SitecoreType(TemplateId = "{Some GUID}")]
public interface INavigationFolder : IItem
{
    [SitecoreChildren(IsLazy = false)]
    IEnumerable<INavigationLink> ChildLinks { get; set; }
}

Navigation Link interface for glass mapper:

[SitecoreType(TemplateId = "{Some GUID}")]
public interface INavigationLink : IItem
{
    [SitecoreField(FieldId = "{Some GUID}")]
    string NavigationTitle { get; set; }

    [SitecoreField(FieldId = "{Some GUID}")]
    IItem NavigationItem { get; set; }

    [SitecoreField(FieldId = "{Some GUID}")]
    Link NavigationGeneralLink { get; set; }

    [SitecoreField(FieldId = "{Some GUID}")]
    string ShortDescription { get; set; }

    [SitecoreChildren(IsLazy = false)]
    IEnumerable<INavigationLink> ChildLinks { get; set; }

}

Note: This will code will generate menu similar to sitecore site

UPDATE

Url property in interface IItem is defined as follows:

[SitecoreType(TemplateId = "{Some GUID}")]
public interface IItem
{
    [SitecoreId()]
    Guid ID { get; }

    [SitecoreInfo(Type = SitecoreInfoType.Language)]
    Language Language { get; }

    [SitecoreInfo(Type = SitecoreInfoType.Version)]
    int Version { get; }

    [SitecoreInfo(Type = SitecoreInfoType.Url)]
    string Url { get; }

    [SitecoreInfo(Type = SitecoreInfoType.TemplateId)]
    Guid TemplateId { get; }

    [SitecoreInfo(Type = SitecoreInfoType.Key)]
    string Key { get; }
}

解决方案

The second expression in the RenderLink methods should resolve to the property that represents the field you want to be editable in the Page Editor, e.g.:

RenderLink(linkitem, x => x.NavigationItem.Url, isEditable: false, contents: linkitem.NavigationTitle));

When you add the additional method call to the end of the expression Glass.Mapper cannot evaluate which field to make editable correctly.

Instead if you want to do something like this you should probably use an if statement to switch between the two renderings:

        if (IsInEditingMode)
        {
            strMenuText.Append(RenderLink(
                linkitem,
                x => x.NavigationItem.Url
                isEditable: false,
                contents: linkitem.NavigationTitle));
        }
        else
        {
            strMenuText.Append(RenderLink(
                linkitem,
                x => x.NavigationItem.Url.StringToLink(),
                isEditable: false,
                contents: linkitem.NavigationTitle));
        }

However I haven't tested this, instead you should update your property to the Link field type and it will automatically map it:

  [SitecoreField]
  public virtual Glass.Mapper.Sc.Fields.Link Url{get;set;}

You can then update the menu code to:

            strMenuText.Append(RenderLink(
                linkitem,
                x => x.NavigationItem.Url
                isEditable: false,
                contents: linkitem.NavigationTitle));

这篇关于异常的玻璃在PageEditor模式映射器Sitecore的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆