简体   繁体   English

如何获取特定页面类型构建器类型的 EPiServer 页面,并正确填充其所有强类型属性?

[英]How do I get an EPiServer page of a specific page type builder type with all its strongly typed properties correctly populated?

How do I get an EPiServer page of a specific page type builder type with all its strongly typed properties correctly populated?如何正确填充所有强类型属性的特定页面类型构建器类型的 EPiServer 页面? Could I do this in a single method call?我可以在一个方法调用中做到这一点吗?

I have tried using:我试过使用:

ContentPageType pageAsContentPageType =  
    DataFactory.Instance.GetPage<ContentPageType>(page.PageLink);

However, this does not work.但是,这不起作用。 It populates the PageData properties but nothing else, despite that I am specifying its target as a ContentPageType.尽管我将其目标指定为 ContentPageType,但它只填充 PageData 属性。

I have included the offending code below, which I have extensively commented:我在下面包含了有问题的代码,我对此进行了广泛的评论:

public static IList<ContentPageType> GetMapEnabledPages()
{
    // Get the content pages
    IList<PageData> pages = PageFactory.GetPages(
                PageReference.StartPage.ID,
                BaseSettings.Constants.EPiServer.PageTypeNames.ContentPage
            );

    // Some content pages will be map enabled pages. So, we need to extract the ones that are put them in this variable.
    IList<ContentPageType> mapEnabledPages = new List<ContentPageType>();

    // walk pages to extract only map enabled pages
    foreach (PageData page in pages)
    {
        // get the page as a ContentPageType. 
        // unfortunately, this method only populates the PageData information and none of the additional strongly types properties that a ContentPageType has.
        // we would expect this happen because EPiServer uses IoC elsewhere but does not do it here.
        ContentPageType pageAsContentPageType =  
            DataFactory.Instance.GetPage<ContentPageType>(page.PageLink);

        // So, we fudge it - we know that the PageData weakly type properties has IsMapEnabled correctly populated. 
        // So, we put that value in the strongly typed ContentPageType property.
        if (pageAsContentPageType != null && pageAsContentPageType["IsMapEnabled"] != null)
        {
            // put that the weakly typed property for "IsMapEnabled" into the strongly typed ContentPageType IsMapEnabled property
            pageAsContentPageType.IsMapEnabled = 
                TypeHelper.ConvertToBoolean(pageAsContentPageType["IsMapEnabled"].ToString());

            // check if it is map enabled
            if (pageAsContentPageType.IsMapEnabled)
            {
                // it is a map enabled page. So, add it to the mapEnabledPages list.
                mapEnabledPages.Add(pageAsContentPageType);
            }
        }
    }
    return mapEnabledPages;
}

EDIT:编辑:

Previously, I tried the following but it does not work either:以前,我尝试了以下方法,但它也不起作用:

ContentPageType pageAsContentPageType = 
    DataFactory.Instance.GetPage(page.PageLink) as ContentPageType 

SOLUTION FOR CMS5R2SP2: CMS5R2SP2 的解决方案:

It turned out that there was a missing virtual keyword on the IsMapEnabled page type property.结果发现 IsMapEnabled 页面类型属性上缺少虚拟关键字。 The IoC container was, therefore, not overriding this property from its default value.因此,IoC 容器不会从其默认值覆盖此属性。 Here is the final implementation:这是最终的实现:

    IList<PageData> pages = PageFactory.GetPages(
            PageReference.StartPage.ID,
            BaseSettings.Constants.EPiServer.PageTypeNames.ContentPage
        );

    // Some content pages will be map enabled pages.
    // So, we need to extract the ones that are put them in this variable.
    IEnumerable<ContentPageType> mapEnabledPages = 
        from page in pages.OfType<ContentPageType>()
        where page.IsMapEnabled
        select page;

    // return map enabled pages.
    return mapEnabledPages.ToList();

SOLUTION FOR CMS6: CMS6 的解决方案:

OfType<ContentPageType>() does not work. OfType<ContentPageType>()不起作用。 So, regetting each page works as Joel said.因此,重新获取每一页就像 Joel 所说的那样。

The GetPage method with the type parameter was introduced in the last version of EPiServer CMS 5 and removed in version 6. So, assuming that you are using version 5 and not a custom extension method the answer is simply to not use the method with the type parameter and instead just cast the result of the call to GetPage (assuming you know the type).带有 type 参数的 GetPage 方法是在 EPiServer CMS 5 的最后一个版本中引入的,并在版本 6 中被删除。因此,假设您使用的是版本 5 而不是自定义扩展方法,答案就是不使用带有类型的方法参数,而只是将调用结果转换为 GetPage(假设您知道类型)。 In other words, the below code should work fine:换句话说,下面的代码应该可以正常工作:

ContentPageType pageAsContentPageType = (ContentPageType) DataFactory.Instance.GetPage(page.PageLink);

Page Type Builder intercepts calls to GetPage and replaces the returned PageData object with a proxy of the correct type. Page Type Builder 拦截对 GetPage 的调用并将返回的 PageData object 替换为正确类型的代理。 This proxy intercepts calls to properties and returns the values.此代理拦截对属性的调用并返回值。 In other words, instances of PTB classes are never actually populated but it's vital that PTB can intercept the calls.换句话说,PTB 类的实例从未真正填充,但 PTB 可以拦截调用至关重要。

The GetPage method with the type parameter was somewhat experimental and while it did allow pages to be returned as a specific type it didn't allow external parties (such as PTB) to replace the object being returned.带有 type 参数的 GetPage 方法在某种程度上是实验性的,虽然它确实允许将页面作为特定类型返回,但它不允许外部方(例如 PTB)替换返回的 object。 It was later removed per request to allow us to create extension methods with the same signature.后来根据请求将其删除,以允许我们创建具有相同签名的扩展方法。

Some history here . 这里有一些历史。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM