Orchardcms Orchard ContentItem的自动路由部分显示URL

Orchardcms Orchard ContentItem的自动路由部分显示URL,orchardcms,orchardcms-1.6,Orchardcms,Orchardcms 1.6,我有一个通过UI构建的自定义内容类型,例如,不是通过一个模块构建的,该模块上有两个字段,其中一个是ContentItemPicker。除了从模型的项目集合中找到ContentItem的友好URL之外,我设法使前端的一切都能正常工作。我看到一些示例,其中我应该使用Url.ImageDisplayUrl[ContentItem],但这给了我一个错误:“System.Web.Mvc.UrlHelper”没有名为“ItemDisplayUrl”的适用方法,但似乎有一个名为“ItemDisplayUrl”

我有一个通过UI构建的自定义内容类型,例如,不是通过一个模块构建的,该模块上有两个字段,其中一个是ContentItemPicker。除了从模型的项目集合中找到ContentItem的友好URL之外,我设法使前端的一切都能正常工作。我看到一些示例,其中我应该使用Url.ImageDisplayUrl[ContentItem],但这给了我一个错误:“System.Web.Mvc.UrlHelper”没有名为“ItemDisplayUrl”的适用方法,但似乎有一个名为“ItemDisplayUrl”的扩展方法。无法动态调度扩展方法。考虑在不使用扩展方法语法的情况下强制转换动态参数或调用扩展方法。 我在顶部的使用说明如下:

@using Orchard.ContentPicker.Fields
@using Orchard.Utility.Extensions;
@using System.Linq
@using Orchard.ContentManagement;
@using Orchard.Mvc.Html;
@using Orchard.Utility.Extensions;
我想我错过了一些东西,但似乎不知道是什么。我构建视图的方式如下所示,我试图获取的URL来自tab.ContentItem.HomepageTab.NavigationItem:

**编辑**

我在顶部有一个HomepageTab的类声明,它与tab.ContentItem.HomepageTag不相关,因为它是动态的,与ContentItem属性无关。它的结构如下:

public class HomepageTab
{
    public dynamic DisplayOrder { get; set; }
    public string ImageUrl { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string ButtonText { get; set; }
    public dynamic ContentItem { get; set; }
    public string TabText { get; set; }
    public string NavigateUrl { get; set; }
    public string TabId
    {
        get { return "t" + this.DisplayOrder.ToString(); }
    }
}
想法?

tab.ContentItem.HomepageTab.NavigationItem是您的内容项选取器字段,但以这种方式表示,它是一个动态对象,因此如果您尝试使用它而不强制转换它,编译器可能会产生各种困惑。所以首先我推荐演员:

var pickerField = tab.ContentItem.HomepageTab.NavigationItem as ContentPickerField;
if (pickerField != null) {
然后,您可以获得字段中的第一个也是唯一一个项目注意,我们可能会在此处导致选择N+1问题,请参见以下内容:

    var firstItem = pickerField.ContentItems.FirstOrDefault();
最后,我们可以询问该项目的显示URL:

    if (firstItem != null) {
        var url = Url.ItemDisplayUrl(firstItem);
这应该很好用。但是要小心:正如我上面所说的,获取每个选项卡的项集合可能会触发每个选项卡的一个新数据库查询,从而降低性能。为了避免这个问题,您可以使用类似于我在本文中描述的技术预取相关内容项:

与预取图像不同,您在这里要做的是首先获取所有免费的相关ID的列表,这些ID存储在字段中,这些字段与您已有的内容项一起存储。然后,您将使用GetMany为项目构建一个ID的本地缓存。最后,您将使用该缓存而不是ContentItems集合从ID中查找项目


我希望这是有意义的。

您能尝试在@Model.Items中为每个IContent选项卡执行操作吗?这将使编译器的类型显式,然后编译器将能够推断出要使用的扩展方法,但“Orchard.ContentManagement.ContentItem”不包含“HomepageTab”的定义,并且没有接受类型为“Orchard.ContentManagement.ContentItem”的第一个参数的扩展方法“HomepageTab”可以找到。AsI更新了问题,以显示HomepageTab的类声明,其中var t=newHomepageTab[…]正在发挥作用。由于我的命名方案在这种情况下有点混乱,当我执行上述操作时,我得到了一个不同的错误,我假设这只是我对Orchard缺乏理解。错误是:“ProjectionWidget\u url\u homepage\u cshtml.HomepageTab”类型不能用作泛型类型或方法“Orchard.ContentManagement.ContentExtensions.AsOrchard.ContentManagement.IContent”中的类型参数“T”。没有来自[…]的隐式引用转换。请删除该类,并尝试使用tab.As代替tab.ContentItem.HomePageTab。如果HomePageTab是您的部件类型。太好了,这完全符合我的需要!我不太关心这个例子中的N+1问题,因为这是一组主页选项卡,其中最多只有~6个,但如果我这样做的话,很高兴知道接下来会发生什么。谢谢
    if (firstItem != null) {
        var url = Url.ItemDisplayUrl(firstItem);