1

对于代码:

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

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

一切正常,直到我尝试使用页面编辑器模式并从 glass mapper api 显示以下错误。

表达式不计算为 Glass.Mapper.Sc.GlassHtml.MakeEditable[T] 中的成员 x.NavigationItem.Url.StringToLink()(表达式1 field, Expression1 标准输出、T 模型、字符串参数、上下文上下文、数据库数据库、TextWriter 编写器)

string注意:StringToLink 是将表单中的外部 url 转换为 Glass 映射器Glass.Mapper.Sc.Fields.Link类型的扩展方法。

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

更新

菜单用户控制代码:

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

玻璃映射器的导航文件夹界面:

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

玻璃映射器的导航链接界面:

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

}

注意:这将代码将生成类似于 sitecore 站点的菜单

更新

接口中的url属性IItem定义如下:

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

2 回答 2

0

扩展方法不是类的“真正”扩展,它们在编译时被解析。在没有看到其余代码的情况下,指出如何重写代码以解决此问题并不容易。我建议类似:

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

然后在你的调用代码中

strMenuText.Append(RenderLink(mainlinkitem, 
        x => MakeLink( x.NavigationItem.Url ), 
        isEditable: true,            
        contents: mainlinkitem.NavigationTitle));
于 2013-09-11T08:17:02.550 回答
0

RenderLink 方法中的第二个表达式应解析为表示您希望在页面编辑器中可编辑的字段的属性,例如:

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

当您将额外的方法调用添加到表达式的末尾时,Glass.Mapper 无法评估哪个字段可以正确编辑。

相反,如果你想做这样的事情,你可能应该使用 if 语句在两个渲染之间切换:

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

但是我没有对此进行测试,相反,您应该将您的属性更新为 Link 字段类型,它会自动映射它:

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

然后,您可以将菜单代码更新为:

            strMenuText.Append(RenderLink(
                linkitem,
                x => x.NavigationItem.Url
                isEditable: false,
                contents: linkitem.NavigationTitle));
于 2013-09-24T06:58:42.897 回答