You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Razor支持内部Razor标记的模板组件方案问询

在ASP.NET Core Razor中实现可复用的带插槽模板组件

针对你需要的“类似Layout但可在同一页面多次使用、支持插入任意Razor标记”的需求,有两种成熟的基于Razor标记文件的方案:

方案1:带模板委托的部分视图(适用于Razor Pages/MVC)

这是传统Razor栈的原生方案,完全基于.cshtml文件,通过RenderFragment类型实现“插槽”功能,允许你定义通用结构并插入自定义内容。

1. 创建通用模板部分视图

新建Shared/ContentCard.cshtml,定义通用页眉页脚,预留内容插槽:

@model RenderFragment

<div style="border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 16px; margin-bottom: 16px;">
    <!-- 通用页眉 -->
    <div class="card-header" style="font-size: 1.2rem; font-weight: bold; margin-bottom: 12px;">
        通用卡片页眉
    </div>

    <!-- 自定义内容插槽 -->
    @Model

    <!-- 通用页脚按钮 -->
    <div class="card-footer" style="margin-top: 12px; text-align: right;">
        <button type="button" class="btn btn-primary">操作按钮</button>
    </div>
</div>

如果需要多个自定义插槽(比如页眉也可自定义),可以扩展为接受多个RenderFragment的动态模型:

@* Shared/ContentCardWithCustomHeader.cshtml *@
@model dynamic

<div style="border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 16px; margin-bottom: 16px;">
    @Model.HeaderContent
    @Model.MainContent
    <div class="card-footer" style="margin-top: 12px; text-align: right;">
        <button type="button" class="btn btn-primary">操作按钮</button>
    </div>
</div>

2. 在页面中调用模板

在任意.cshtml页面(如Index.cshtml)中,通过Html.PartialAsync传递自定义Razor内容:

@* 单插槽模板调用 *@
@await Html.PartialAsync("~/Shared/ContentCard.cshtml", @<text>
    <p>普通文本内容</p>
    <form method="post">
        <input name="username" placeholder="用户名" />
        <button type="submit">提交</button>
    </form>
</text>)

@* 多次调用,插入复杂渲染内容 *@
@await Html.PartialAsync("~/Shared/ContentCard.cshtml", @<text>
    <h3>动态列表</h3>
    <ul>
        @foreach (var item in Model.ProductList)
        {
            <li>@item.Name - @item.Price</li>
        }
    </ul>
</text>)

@* 多插槽模板调用 *@
@await Html.PartialAsync("~/Shared/ContentCardWithCustomHeader.cshtml", new {
    HeaderContent = (RenderFragment)(@<text>
        <div style="color: #28a745;">自定义标题</div>
    </text>),
    MainContent = (RenderFragment)(@<text>
        <p>带自定义页眉的卡片内容</p>
    </text>)
})

方案2:Razor组件(适用于ASP.NET Core 3.0+)

如果你的项目支持Razor组件(包括Blazor Server/WASM,或Razor Pages/MVC集成组件),这是更简洁的现代方案,基于.razor文件(本质是Razor标记):

1. 创建Razor组件

新建Shared/ContentCard.razor:

<div style="border: 1px solid #ddd; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); padding: 16px; margin-bottom: 16px;">
    <div class="card-header" style="font-size: 1.2rem; font-weight: bold; margin-bottom: 12px;">
        @HeaderText
    </div>

    <!-- 内置内容插槽 -->
    @ChildContent

    <div class="card-footer" style="margin-top: 12px; text-align: right;">
        <button type="button" class="btn btn-primary" @onclick="HandleButtonClick">操作按钮</button>
    </div>
</div>

@code {
    [Parameter]
    public string HeaderText { get; set; } = "通用卡片页眉";

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    private void HandleButtonClick()
    {
        // 可选:添加按钮点击逻辑
    }
}

2. 在页面中调用组件

在Razor Pages/MVC页面中需先启用组件支持,之后直接调用:

@* 调用组件,传入自定义内容 *@
<component type="typeof(ContentCard)" render-mode="ServerPrerendered">
    <div>
        <p>自定义Razor内容</p>
        @foreach (var item in Model.CategoryList)
        {
            <span>@item.DisplayName</span>
        }
    </div>
</component>

<component type="typeof(ContentCard)" render-mode="ServerPrerendered" param-HeaderText="第二个卡片">
    <form>
        <input type="email" placeholder="输入邮箱" />
        <button type="submit">订阅</button>
    </form>
</component>

方案优势

  • 完全基于Razor标记文件,无需C#硬编码HTML
  • 支持在同一页面多次调用,每次传入不同的自定义内容
  • 兼容任意复杂Razor内容:循环、条件渲染、表单、嵌套其他模板/组件

内容的提问来源于stack exchange,提问作者Alex from Jitbit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:40:19