ASP.NET Razor 标记(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在 Web 开发领域,开发者常常需要将静态的 HTML 与动态的后端逻辑无缝结合。ASP.NET Razor 标记正是为此而生——它通过简洁的语法,让开发者能够在 HTML 中直接嵌入 C# 代码,实现视图层与业务逻辑的高效协作。无论是编程初学者还是有一定经验的开发者,掌握这一工具都能显著提升开发效率。本文将从基础到进阶,结合实际案例,带您全面理解 ASP.NET Razor 标记的核心功能与应用场景。
基础语法:HTML 与 C# 的“共生关系”
什么是 Razor 标记?
Razor 是 ASP.NET 提供的一种语法,允许开发者在 HTML 文件中直接编写 C# 代码。它通过 @
符号区分 HTML 内容和代码块,例如:
<p>当前时间:@DateTime.Now</p>
这段代码会将服务器的当前时间动态渲染到页面中。
核心概念:代码块与表达式
Razor 的语法分为两类:
- 表达式(Expression):以
@
开头,直接输出结果。例如:<div>用户数量:@UserCount</div>
- 代码块(Code Block):用
@{ ... }
包裹,执行复杂逻辑。例如:@{ var message = "欢迎访问!"; if (IsLoggedIn) { message += " 请开始您的探索!"; } } <h1>@message</h1>
形象比喻:Razor 是 HTML 的“智能翻译官”
想象 HTML 是一本静态的书,而 Razor 就像一个能理解 C# 的翻译官,它读取代码并将其转化为动态内容。例如,当用户访问页面时,Razor 会将 @DateTime.Now
翻译成实际的时间值,再将结果插入到 HTML 中。
条件判断与循环:动态内容的“指挥棒”
条件语句:根据逻辑展示不同内容
通过 @if
、@else if
、@else
结构,开发者可以控制页面元素的显示。例如:
@{
var userRole = "admin";
}
@if (userRole == "admin") {
<div>您有管理员权限</div>
} else if (userRole == "guest") {
<div>请登录以解锁更多功能</div>
} else {
<div>未知角色</div>
}
案例:用户权限控制
假设一个电商网站需要根据用户角色显示不同的菜单项:
<ul>
@if (User.IsInRole("Admin")) {
<li><a href="/admin">管理后台</a></li>
}
@if (User.IsAuthenticated) {
<li><a href="/orders">我的订单</a></li>
}
</ul>
循环结构:批量渲染列表数据
通过 @foreach
,可以遍历集合并生成 HTML 元素。例如:
<ul>
@foreach (var product in products) {
<li>@product.Name - @product.Price 元</li>
}
</ul>
实际场景:显示商品列表
假设有一个 Product
对象列表:
public class Product {
public string Name { get; set; }
public decimal Price { get; set; }
}
在 Razor 视图中,可以这样渲染:
<table>
<thead>
<tr><th>名称</th><th>价格</th></tr>
</thead>
<tbody>
@foreach (var product in Model.Products) {
<tr>
<td>@product.Name</td>
<td>@product.Price</td>
</tr>
}
</tbody>
</table>
表单处理与数据绑定:用户交互的“枢纽”
基础表单:收集用户输入
通过 Razor 的 Html.BeginForm()
辅助方法,可以快速生成表单。例如:
@using (Html.BeginForm("Submit", "Home", FormMethod.Post)) {
<label>姓名:@Html.TextBoxFor(m => m.Name)</label>
<label>邮箱:@Html.TextBoxFor(m => m.Email)</label>
<input type="submit" value="提交" />
}
此代码会生成一个提交到 Home/Submit
的表单,并自动绑定模型(Model)中的 Name
和 Email
属性。
强类型视图:模型驱动的开发
使用 @model
指令声明视图绑定的模型类型,例如:
@model MyProject.Models.UserRegistrationViewModel
这允许开发者直接访问模型属性,例如:
<p>欢迎,@Model.UserName!</p>
案例:用户注册表单
假设有一个 UserRegistrationViewModel
模型:
public class UserRegistrationViewModel {
[Required]
public string UserName { get; set; }
[EmailAddress]
public string Email { get; set; }
}
对应的视图代码可以这样编写:
@model UserRegistrationViewModel
@using (Html.BeginForm()) {
@Html.LabelFor(m => m.UserName)
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email)
<input type="submit" value="注册" />
}
布局与继承:模块化开发的“蓝图”
布局页(Layout):统一页面结构
通过 _Layout.cshtml
文件,可以定义网站的通用结构(如导航栏、页脚)。例如:
<!-- _Layout.cshtml -->
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
</head>
<body>
<nav>
<ul>
<li>@Html.ActionLink("首页", "Index", "Home")</li>
<li>@Html.ActionLink("关于", "About", "Home")</li>
</ul>
</nav>
<div>
@RenderBody() <!-- 子视图内容插入点 -->
</div>
<footer>© 2023 My Website</footer>
</body>
</html>
子视图继承布局页
在子视图中通过 Layout
指令指定布局页:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!-- 子视图内容 -->
<h1>欢迎来到首页</h1>
部分视图(Partial View):复用组件
通过 Html.Partial()
或 Html.RenderPartial()
渲染共享组件。例如:
<!-- _CommentList.cshtml 部分视图 -->
@foreach (var comment in Model) {
<div class="comment">
<p>@comment.Content</p>
<small>by @comment.Author</small>
</div>
}
在主视图中调用:
@Html.Partial("_CommentList", Model.Comments)
高级用法:Razor 的隐藏能力
自定义 HTML 辅助方法
通过扩展 HtmlHelper
,可以封装常用功能。例如,一个分页导航辅助方法:
public static class HtmlHelpers {
public static IHtmlContent Pagination(this HtmlHelper html, int currentPage, int totalPages) {
var sb = new StringBuilder();
sb.Append("<ul class='pagination'>");
for (int i = 1; i <= totalPages; i++) {
sb.Append($"<li class='page-item { (i == currentPage ? "active" : "") }'>");
sb.Append($"<a class='page-link' href='?page={i}'>{i}</a>");
sb.Append("</li>");
}
sb.Append("</ul>");
return new HtmlString(sb.ToString());
}
}
在视图中使用:
@Html.Pagination(CurrentPage, TotalPages)
静态资源引用:@Url.Content()
通过 @Url.Content()
辅助方法引用静态资源,确保路径正确:
<link rel="stylesheet" href="@Url.Content("~/css/styles.css")" />
常见问题与解决方案
1. 代码块未闭合导致解析错误
现象:页面显示错误提示“未找到分隔符 }
”。
解决:检查 @{ ... }
内部的代码是否缺少 }
,或使用缩进确保代码块结构清晰。
2. 动态内容未渲染
现象:页面显示 @DateTime.Now
而非实际时间。
原因:视图未正确绑定模型或未使用 Razor 标记。
解决:确保代码位于 .cshtml
文件中,并检查 @
符号是否被转义。
3. 表单提交后数据丢失
现象:表单提交后,页面刷新时输入内容消失。
解决:在 POST 动作中重新传递模型数据,或使用 TempData
临时存储。
案例实战:构建用户管理系统
需求描述
创建一个简单的用户管理页面,包含以下功能:
- 显示用户列表
- 添加新用户
- 编辑用户信息
代码实现
1. 用户模型
public class User {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
2. 控制器
public class UserController : Controller {
private List<User> Users = new List<User>();
public ActionResult Index() {
return View(Users);
}
[HttpPost]
public ActionResult Add(User user) {
Users.Add(user);
return RedirectToAction("Index");
}
}
3. Razor 视图(Index.cshtml)
@model List<User>
@{
ViewBag.Title = "用户列表";
}
<h1>用户管理</h1>
<!-- 添加用户表单 -->
<form method="post" action="/User/Add">
<input type="text" name="Name" placeholder="用户名" required />
<input type="email" name="Email" placeholder="邮箱" required />
<button type="submit">添加用户</button>
</form>
<!-- 用户列表 -->
<table>
<thead>
<tr><th>名称</th><th>邮箱</th></tr>
</thead>
<tbody>
@foreach (var user in Model) {
<tr>
<td>@user.Name</td>
<td>@user.Email</td>
</tr>
}
</tbody>
</table>
结论
ASP.NET Razor 标记通过简洁的语法和强大的功能,为动态 Web 开发提供了高效且直观的解决方案。从基础的条件判断、循环结构,到高级的布局继承和自定义辅助方法,它始终以“让 HTML 与 C# 自然协作”为核心目标。无论是构建简单的表单,还是复杂的管理系统,Razor 都能帮助开发者快速实现需求,同时保持代码的可维护性与可读性。
掌握这一工具后,开发者可以进一步探索 ASP.NET Core 的更多特性,如中间件、依赖注入等,从而构建出更健壮、可扩展的 Web 应用。希望本文能成为您学习 ASP.NET Razor 标记的起点,并在实际项目中发挥价值。