如何更改管道中的 RenderingContext?
How do I alter the RenderingContext in a pipeline?
我需要一个管道来拦截 sitecore RenderingContext
的构建,特别是我需要即时更改 RenderingContext.Current.Rendering.DataSource
属性。
我需要这样做,因为我在 sitecore 的数据源中添加了一个变量。我在控制器中对此进行了操作,但是当我打开体验编辑器时,它甚至在碰到我的控制器之前就倒下了。我猜更高层需要数据源有效。
经过一番挖掘,我发现了这条管道:
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;
}
}
我需要一个管道来拦截 sitecore RenderingContext
的构建,特别是我需要即时更改 RenderingContext.Current.Rendering.DataSource
属性。
我需要这样做,因为我在 sitecore 的数据源中添加了一个变量。我在控制器中对此进行了操作,但是当我打开体验编辑器时,它甚至在碰到我的控制器之前就倒下了。我猜更高层需要数据源有效。
经过一番挖掘,我发现了这条管道:
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;
}
}