2016-01-06 51 views
3

我需要一個管道來攔截網站內核RenderingContext的建築物,具體而言,我需要隨時更改RenderingContext.Current.Rendering.DataSource屬性。如何修改管道中的RenderingContext?

我需要這樣做,因爲我在sitecore的數據源中添加了一個變量。我在控制器中操縱了這個,但是當我打開體驗編輯器時,它在它擊中我的控制器之前就會崩潰。我猜想更高級的數據源需要有效。

回答

1

有點挖約我之後發現這條管道:

namespace Sitecore.Mvc.Pipelines.Response.RenderRendering 
{ 
    public class EnterRenderingContext : RenderRenderingProcessor 
    { 
     public override void Process(RenderRenderingArgs args) 
     { 
      Assert.ArgumentNotNull(args, "args"); 
      if (args.Rendered) 
      { 
       return; 
      } 
      this.EnterContext(args.Rendering, args); 
     } 

     protected virtual void EnterContext(Rendering rendering, RenderRenderingArgs args) 
     { 
      IDisposable item = RenderingContext.EnterContext(rendering); 
      args.Disposables.Add(item); 
     } 
    } 
} 

反映出來的Sitecore.Mvc.dll


現在我可以用我自己替換此管道與前更改RenderingContext的值他們的內置:

public class RedrowEnterRenderingContext : Sitecore.Mvc.Pipelines.Response.RenderRendering.EnterRenderingContext 
{ 
    private const string _developmentKeyword = "$development"; 

    private IDevelopmentQueryServiceV2 _coUkDevelopmentQueryService = ServiceLocator.Current.GetInstance<IDevelopmentQueryServiceV2>(); 


    protected override void EnterContext(Rendering rendering, RenderRenderingArgs args) 
    { 

     //Make your changes to the items that are used to build the context here 
     if (args.PageContext != null && 
      args.PageContext.Item != null && 
      args.Rendering.DataSource.Contains(_developmentKeyword) && 
      args.PageContext.Item.TemplateID.Guid == TemplateIdConst.V2Development) 
     { 

      args.Rendering.DataSource = args.Rendering.DataSource.Replace(_developmentKeyword, 
       args.PageContext.Item.Paths.Path); 
     } 
     //build the context using the existing functionality 
     base.EnterContext(rendering, args); 
    } 
} 

我是男人在特定的場景中使用數據源,但是這個代碼可以適用於做很多工作。

你這樣註冊的:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> 
    <sitecore> 
    <pipelines> 
     <mvc.renderRendering> 
     <processor type="Namespace.MyEnterRenderingContext, DLLName" 
        patch:instead="*[@type='Sitecore.Mvc.Pipelines.Response.RenderRendering.EnterRenderingContext, Sitecore.Mvc']"/> 
     </mvc.renderRendering> 
    </pipelines> 
    </sitecore> 
</configuration> 

一個問題與此的是,它在BrokenLinkValidator顯示出來。您可以覆蓋這雖然並創建自己:

[Serializable] 
public class MyBrokenLinksValidator : BrokenLinkValidator 
{ 
    public RedrowBrokenLinksValidator() : base() 
    { 

    } 

    public RedrowBrokenLinksValidator(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) 
    { 
    } 

    protected override ValidatorResult Evaluate() 
    { 
     ValidatorResult returnVal = base.Evaluate(); 
     if (returnVal != ValidatorResult.Valid) 
     { 
      Item obj = base.GetItem(); 
      ItemLink[] brokenLinks = obj.Links.GetBrokenLinks(false); 
      //are all the broken links basically because they are contextual? 
      if (brokenLinks.All(a => a.TargetPath.Contains("$development"))) 
      { 
       foreach (ItemLink brokenLink in brokenLinks) 
       { 
        Database database = Sitecore.Configuration.Factory.GetDatabase("master"); 
        //try again but replacing the varible with a context 
        var secondTryPath = brokenLink.TargetPath.Replace(
         "$development", obj.Paths.Path); 

        Item secondTryItem = database.GetItem(secondTryPath); 
        if (secondTryItem == null) 
         return returnVal; 
       } 

       //if we've got here then all the links are valid when adding the context 
       return ValidatorResult.Valid; 
      } 
     } 

     return returnVal; 
    } 
} 
+1

我確實在我的博客文章類似的東西在這裏:http://sitecore-estate.nl/wp/2014/08/queryable-datasource-on-sublayouts/ 這不是MVC壽,但可能有助於有時使用它。 – Younes

+0

我來看看@Younes。我寫這篇文章是因爲我努力尋找關於這個主題的任何文檔。 – Liam