在 Sitecore 中使用 @Html.Partial 渲染公共视图是否可行?
结论
可以使用 @Html.Partial() 提取并渲染公共 Razor 视图。如果这部分 HTML 不需要成为独立的 Sitecore 组件,也不需要独立的数据源、个性化、Experience Editor 编辑能力或组件级缓存,就不必改用 @Html.Sitecore().Rendering()。
但不能简单地认为,嵌套在父视图中的内容一定会被缓存。只有父 Sitecore rendering 启用了 HTML 缓存,并正确配置了缓存变化条件,最终生成的整段 HTML(包括 partial 的输出)才会随父 rendering 一起缓存。
两种 Helper 的区别
@Html.Partial() 是标准的 MVC Razor 功能。它会查找 partial view,并使用当前模型或指定模型渲染 HTML:
@Html.Partial("_PaymentInformationCommon", Model)
它不会创建新的 Sitecore rendering,也不会单独进入 Sitecore 的组件渲染流程。
@Html.Sitecore().Rendering() 用于渲染 Sitecore 中定义的组件。公共部分需要以下能力时,才适合使用它:
- 独立配置数据源
- 参与 Sitecore 个性化或条件渲染
- 在 Experience Editor 中作为独立组件编辑
- 使用自己的 rendering parameters
- 独立启用和控制 Sitecore HTML 缓存
- 根据设备、数据源或其他 Sitecore 上下文单独变化
- 允许内容编辑人员单独添加、删除或调整位置
如果公共 HTML 只是用于复用两个视图中的代码,partial view 通常更简单,也更符合 Razor 视图的职责。
推荐实现方式
可以将公共部分保存为普通的 partial view,例如:
/Views/Payment/_PaymentInformationCommon.cshtml
在 partial view 中声明它实际需要的模型:
@model PaymentInformationViewModel
<div class="payment-information">
<div class="payment-information__method">
@Model.PaymentMethod
</div>
<div class="payment-information__amount">
@Model.Amount
</div>
</div>
然后在两个由 Sitecore 配置的主视图中分别调用它。
Payment Information.cshtml:
@model PaymentInformationViewModel
<section class="payment">
<h2>Payment Information</h2>
@Html.Partial("_PaymentInformationCommon", Model)
</section>
Agent Payment Information.cshtml:
@model AgentPaymentInformationViewModel
<section class="agent-payment">
<h2>Agent Payment Information</h2>
@Html.Partial(
"_PaymentInformationCommon",
Model.PaymentInformation
)
</section>
如果两个页面使用不同的模型,建议为公共 partial 定义一个较小且职责明确的共享模型,不要让它依赖整个页面模型:
public class PaymentInformationViewModel
{
public string PaymentMethod { get; set; }
public decimal Amount { get; set; }
}
这样可以避免公共视图与某个 Sitecore rendering model 绑定得太紧。
缓存行为
Html.Partial() 不会创建独立的 Sitecore HTML 缓存条目。它生成的 HTML 会直接成为父 rendering 输出的一部分。
父 rendering 启用 Sitecore HTML 缓存后,缓存过程大致如下:
父 Sitecore rendering 开始渲染
└── 执行主 Razor view
└── 执行 Html.Partial()
最终合并为一段 HTML
└── 作为父 rendering 的输出写入缓存
后续命中父 rendering 缓存时,Sitecore 通常会直接返回已经生成的完整 HTML,不再执行主视图和 partial view。
只有实际启用缓存的父 rendering 才会产生缓存。是否启用,以及是否按照数据源、设备、登录状态或查询字符串等条件区分缓存,取决于项目使用的 Sitecore 版本和 rendering 配置。
例如,输出依赖当前数据源时,应确保缓存按数据源变化。输出与当前用户有关时,则要谨慎使用共享 HTML 缓存,以免将某个用户的内容返回给其他用户。
需要特别注意的情况
不要假设 partial 有独立的 Sitecore 上下文
Html.Partial() 不会建立新的 Sitecore rendering context。partial 读取到的仍是父 rendering 执行期间的上下文。
因此,不应把它当成独立组件,也不能依赖所谓的“当前 partial 自己的数据源”:
RenderingContext.Current.Rendering.DataSource
这里取得的仍是父 rendering 的数据源,并非 partial 独有的数据源。
如果公共部分需要使用不同的数据源,更适合将它配置为独立的 Sitecore rendering,并通过以下方式渲染:
@Html.Sitecore().Rendering(renderingId)
也可以使用项目当前采用的占位符或组件组合方式。
显式传递模型
某些 Html.Partial() 重载可以继承当前视图的模型和 ViewData,但显式传递模型更清楚,也能减少模型类型不匹配的问题:
@Html.Partial("_PaymentInformationCommon", Model.PaymentInformation)
如果 partial 只需要少量展示数据,可以为它创建专用 view model。
不要在 partial 中依赖独立缓存
partial 的内容只能随父 rendering 一起缓存,无法单独设置 Sitecore 缓存变化规则。如果公共部分的更新频率或变化维度与父组件不同,更适合将它设计成独立的 Sitecore rendering。
Experience Editor 能力有限
普通 Razor partial 不会作为独立组件出现在页面布局中,内容编辑人员也无法单独移动、删除或个性化它。
如果 partial 中仍然使用 Sitecore 字段 Helper,例如:
@Html.Sitecore().Field("Payment Title", Model.Item)
字段能否正常编辑,还取决于传入的 Item、页面模式和项目的具体实现。即使字段可以编辑,partial 本身仍不是独立的 Sitecore 组件。
如何选择
如果只是要消除两个 Razor 视图中重复的 HTML,使用 @Html.Partial() 是合理且常见的做法。
如果公共部分以后需要独立的数据源、缓存、个性化、参数配置或 Experience Editor 组件管理,就应将它改为 Sitecore rendering,并使用 @Html.Sitecore().Rendering() 或占位符进行组合。
当前方案可以继续使用,但需要确认父 rendering 已经启用缓存,并检查缓存变化条件是否覆盖了该 partial 依赖的全部数据。
备注:内容仅供参考。
