Orchard ContentItem 的 AutoroutePart DisplayUrl
Orchard ContentItem's AutoroutePart DisplayUrl
我有一个通过 UI(例如,不是通过模块)构建的自定义内容类型,它有几个字段,其中一个是 ContentItemPicker。除了从模型的项目集合中找到 ContentItem 的友好 URL 之外,我设法让前端为此工作。我看到一些我应该使用 Url.ImageDisplayUrl([ContentItem])
的示例,但这给了我这个错误:'System.Web.Mvc.UrlHelper' has no applicable method named 'ItemDisplayUrl' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
我上面的using语句如下:
@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
:
/** @Model.Items is a collection of my custom content types that were created through the UI **/
foreach (var tab in @Model.Items)
{
var t = new SliderTab
{
DisplayOrder = tab.ContentItem.HomepageTab.DisplayOrder.Value,
ButtonText = tab.ContentItem.HomepageTab.ButtonText.Value,
Description = tab.ContentItem.HomepageTab.Description.Value,
ImageUrl = tab.ContentItem.HomepageTab.Image.Url,
Title = tab.ContentItem.TitlePart.Title,
ContentItem = tab.ContentItem,
TabText = tab.ContentItem.HomepageTab.TabText.Value
};
/** HomepageTab is the custom content type created in the Orchard UI which has a ContentPickerField associated with it. The name on that is NavigationItem, so I just need the friendly URL off of a ContentPickerField's associated ContentItem **/
if (tab.ContentItem.HomepageTab.NavigationItem != null && tab.ContentItem.HomepageTab.NavigationItem.Ids != null)
{
//this is way, super hacky - getting the actual friendly URL would be better
t.NavigateUrl = "/Contents/Item/Display/" + tab.ContentItem.HomepageTab.NavigationItem.Ids[0];
}
tabs.Add(t);
}
** 编辑 **
我在顶部有一个 HomepageTab 的 class 声明,它与 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) {
然后您可以获得该字段中的第一个也是唯一一个项目(注意,我们可能会在此处引起 select N+1 问题,见下文):
var firstItem = pickerField.ContentItems.FirstOrDefault();
最后,我们可以要求显示 URL 该项目:
if (firstItem != null) {
var url = Url.ItemDisplayUrl(firstItem);
这应该可以正常工作。但是要小心:正如我上面所说,获取每个选项卡的项目集合可能会为每个选项卡触发一个新的数据库查询,从而降低性能。为避免该问题,您可以使用类似于我在此 post 中描述的技术预取相关内容项:https://weblogs.asp.net/bleroy/speeding-up-pages-with-lots-of-media-content-items
您在这里要做的不是预取图像,而是首先获取所有相关 ID 的列表(这是免费的,这些 ID 存储在字段中,这些字段与您已有的内容项一起存储).然后,您将使用 GetMany
为项目构建 id 的本地缓存。最后,您将使用该缓存而不是 ContentItems
集合来从 ID 中查找项目。
我希望这是有道理的。
我有一个通过 UI(例如,不是通过模块)构建的自定义内容类型,它有几个字段,其中一个是 ContentItemPicker。除了从模型的项目集合中找到 ContentItem 的友好 URL 之外,我设法让前端为此工作。我看到一些我应该使用 Url.ImageDisplayUrl([ContentItem])
的示例,但这给了我这个错误:'System.Web.Mvc.UrlHelper' has no applicable method named 'ItemDisplayUrl' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
我上面的using语句如下:
@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
:
/** @Model.Items is a collection of my custom content types that were created through the UI **/
foreach (var tab in @Model.Items)
{
var t = new SliderTab
{
DisplayOrder = tab.ContentItem.HomepageTab.DisplayOrder.Value,
ButtonText = tab.ContentItem.HomepageTab.ButtonText.Value,
Description = tab.ContentItem.HomepageTab.Description.Value,
ImageUrl = tab.ContentItem.HomepageTab.Image.Url,
Title = tab.ContentItem.TitlePart.Title,
ContentItem = tab.ContentItem,
TabText = tab.ContentItem.HomepageTab.TabText.Value
};
/** HomepageTab is the custom content type created in the Orchard UI which has a ContentPickerField associated with it. The name on that is NavigationItem, so I just need the friendly URL off of a ContentPickerField's associated ContentItem **/
if (tab.ContentItem.HomepageTab.NavigationItem != null && tab.ContentItem.HomepageTab.NavigationItem.Ids != null)
{
//this is way, super hacky - getting the actual friendly URL would be better
t.NavigateUrl = "/Contents/Item/Display/" + tab.ContentItem.HomepageTab.NavigationItem.Ids[0];
}
tabs.Add(t);
}
** 编辑 **
我在顶部有一个 HomepageTab 的 class 声明,它与 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) {
然后您可以获得该字段中的第一个也是唯一一个项目(注意,我们可能会在此处引起 select N+1 问题,见下文):
var firstItem = pickerField.ContentItems.FirstOrDefault();
最后,我们可以要求显示 URL 该项目:
if (firstItem != null) {
var url = Url.ItemDisplayUrl(firstItem);
这应该可以正常工作。但是要小心:正如我上面所说,获取每个选项卡的项目集合可能会为每个选项卡触发一个新的数据库查询,从而降低性能。为避免该问题,您可以使用类似于我在此 post 中描述的技术预取相关内容项:https://weblogs.asp.net/bleroy/speeding-up-pages-with-lots-of-media-content-items
您在这里要做的不是预取图像,而是首先获取所有相关 ID 的列表(这是免费的,这些 ID 存储在字段中,这些字段与您已有的内容项一起存储).然后,您将使用 GetMany
为项目构建 id 的本地缓存。最后,您将使用该缓存而不是 ContentItems
集合来从 ID 中查找项目。
我希望这是有道理的。