@helper:返回 HTML 片段
@helper 用来输出 HTML 片段,本质返回 HelperResult。调用方式与普通 C# 方法一致:
@helper WelcomeMessage(string username)
{
<p>Welcome, @username.</p>
}
@WelcomeMessage("Alice")
特征:
- 方法体内可以直接写 Razor / HTML
- 返回类型只能是
HelperResult,没有别的选择 - 常用于把一段重复 HTML 抽成可复用片段
@helper 是 ASP.NET Web Pages 的特性;MVC 视图里能用但并不常见,PartialView / ViewComponent 才是更标准的复用方式。@functions:写普通 C#
@functions 块里写普通 C# 方法:
@functions {
public string GetSomeString()
{
return string.Empty;
}
public static HtmlString WelcomeMessage(string username)
{
return new HtmlString($"<p>Welcome, {username}.</p>");
}
}
特征:
- 适合纯计算 / 业务逻辑,不渲染 HTML
- 如果要返回 HTML,必须显式返回
HtmlString(不能是string,否则会被 HTML 转义) using System.Web.Mvc;在 MVC 5 之前需要;在 ASP.NET Core 下是Microsoft.AspNetCore.Html.HtmlString
对比
| @helper | @functions | |
|---|---|---|
| 是否必须渲染 HTML | 是 | 否 |
| 返回类型 | 固定 HelperResult | 任意 |
| 适合的场景 | 复用 HTML 片段 | 复用纯逻辑 |
| 现代替代 | Partial View / View Component / Tag Helper | 服务类 + 依赖注入 |
现代替代:ASP.NET Core 怎么做
在 ASP.NET Core 中,把"渲染 HTML 片段"和"写业务方法"两件事都拆出去,不再放在视图里:
复用 HTML:Partial View / View Component / Tag Helper
HTML 片段的复用:
// Views/Shared/_Greeting.cshtml
@model string
<p>Welcome, @Model.</p>
@* 调用方式 *@
@await Html.PartialAsync("_Greeting", "Alice")
@* 或 *@
<partial name="_Greeting" model="Alice" />
带逻辑的可复用块用 View Component:
// Components/CartSummaryViewComponent.cs
public class CartSummaryViewComponent : ViewComponent
{
private readonly ICartService _cart;
public CartSummaryViewComponent(ICartService cart) => _cart = cart;
public IViewComponentResult Invoke() => View(_cart.Current());
}
// Views/Shared/Components/CartSummary/Default.cshtml
@model Cart
<div>共 @Model.Items.Count 件商品</div>
// 调用
@await Component.InvokeAsync("CartSummary")
需要自定义标签就用 Tag Helper:
[HtmlTargetElement("greeting")]
public class GreetingTagHelper : TagHelper
{
public string For { get; set; } = "";
public override void Process(TagHelperContext ctx, TagHelperOutput output)
{
output.TagName = "p";
output.Content.SetContent($"Welcome, {For}.");
}
}
// 视图
<greeting for="Alice" />
复用逻辑:服务类 + DI
不要在视图里写业务方法。提到服务类中:
public interface IGreetingFormatter
{
string Format(string name);
}
public class GreetingFormatter : IGreetingFormatter
{
public string Format(string name) => $"Welcome, {name}.";
}
// 在控制器中注入
public class HomeController(IGreetingFormatter fmt) : Controller
{
public IActionResult Index() => View(model: fmt.Format("Alice"));
}
视图只负责渲染,所有"逻辑"都通过 @inject 拿到的服务或者模型本身来完成:
@inject IGreetingFormatter Greeting
<p>@Greeting.Format("Alice")</p>
从老项目迁移时的取舍
@helper WelcomeMessage(name)→ Partial View_Greeting.cshtml@functions { HtmlString Foo() }→ 抽到 service 类,@inject或通过模型传入- 需要修改多个视图的统一逻辑 → Tag Helper
- 重业务、可单元测试的代码 → View Component 或 Controller 行为
使用准则
@helper/@functions只能出现在.cshtml,单元测试困难,能不用就不用。- ASP.NET Core 项目里,HTML 复用首选
<partial>+ View Component;业务逻辑用服务类 + DI。 - 维护老 MVC 5 项目时,
@helper仅用于纯 HTML 片段;纯逻辑请用@functions或抽到 Helper 类。