PAYATHON 2026

在 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 依赖的全部数据。

备注:内容仅供参考。