【保姆级】ASP.NET Razor 视图引擎:@if/@foreach 核心语法拆解(附避坑指南 + 生活类比)

目录

    • [一、前置认知:Razor 视图引擎的 "指令标记"------@符号的核心作用](#一、前置认知:Razor 视图引擎的 “指令标记”——@符号的核心作用)
    • [二、核心语法 1:@if 条件判断 ------ 像生活中 "根据条件做选择"](#二、核心语法 1:@if 条件判断 —— 像生活中 “根据条件做选择”)
      • [2.1 基础语法(代码示例)](#2.1 基础语法(代码示例))
      • [2.2 嵌套 @if(复杂条件判断)](#2.2 嵌套 @if(复杂条件判断))
      • [2.3 生活类比:奶茶店点单逻辑](#2.3 生活类比:奶茶店点单逻辑)
      • [2.4 @if 高频踩坑点(附解决方案)](#2.4 @if 高频踩坑点(附解决方案))
    • [三、核心语法 2:@foreach 循环遍历 ------ 像生活中 "批量处理重复事务"](#三、核心语法 2:@foreach 循环遍历 —— 像生活中 “批量处理重复事务”)
      • [3.1 基础语法(代码示例)](#3.1 基础语法(代码示例))
      • [3.2 嵌套 @foreach(复杂列表)](#3.2 嵌套 @foreach(复杂列表))
      • [3.3 生活类比:快递员派件逻辑](#3.3 生活类比:快递员派件逻辑)
      • [3.4 @foreach 高频踩坑点(附解决方案)](#3.4 @foreach 高频踩坑点(附解决方案))
    • [四、@if/@foreach 执行流程(可视化流程图)](#四、@if/@foreach 执行流程(可视化流程图))
      • [4.1 @if 条件判断执行流程](#4.1 @if 条件判断执行流程)
      • [4.2 @foreach 循环遍历执行流程](#4.2 @foreach 循环遍历执行流程)
    • [五、实战案例:综合使用 @if+@foreach(商城订单列表)](#五、实战案例:综合使用 @if+@foreach(商城订单列表))
    • 六、结尾互动

作为ASP.NET开发者,Razor 视图引擎是连接后端逻辑与前端 UI 的 "桥梁",而@if(条件判断)和@foreach(循环遍历)则是这座桥梁上最常用的 "建材"。很多新手在使用这两个核心语法时,要么写得 "漏洞百出",要么踩中隐藏的坑导致页面渲染异常。

本文将用生活类比 + 完整代码示例 + 高频踩坑指南 ,把@if和@foreach讲得通俗易懂,即使是刚接触 Razor 的新手也能快速掌握,同时规避 90% 的常见错误。

一、前置认知:Razor 视图引擎的 "指令标记"------@符号的核心作用

在拆解@if和@foreach前,先搞懂 Razor 最基础的核心:@符号。

Razor 视图引擎的本质是 "混合 C# 逻辑与 HTML 标签",而@就是 "切换开关"------ 当解析到@时,引擎会从 "HTML 渲染模式" 切换到 "C# 逻辑执行模式",执行完后再切回 HTML 模式。
生活类比

这就像菜谱里的 "⚠️" 标记:看到这个标记,你就知道接下来是 "需要注意的操作步骤"(对应 C# 逻辑),标记结束后回到 "正常烹饪步骤"(对应 HTML 渲染)。
基础示例

html 复制代码
<!-- HTML模式 -->
<h1>欢迎来到我的页面</h1>
<!-- @切换到C#模式,输出变量值 -->
<p>当前时间:@DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")</p>

小节

@是 Razor 的 "核心开关",所有 C# 逻辑(包括@if/@foreach)都必须以@开头,这是后续语法的基础。

二、核心语法 1:@if 条件判断 ------ 像生活中 "根据条件做选择"

@if是 Razor 中最常用的条件判断语法,用于 "根据不同条件渲染不同 UI 内容",对应生活中 "根据场景做选择" 的场景。

2.1 基础语法(代码示例)

先定义后端传递的模型(以ASP.NET MVC 为例):

csharp 复制代码
// 后端Controller传递的模型
public class UserInfo
{
    public string UserName { get; set; }
    public int UserLevel { get; set; } // 1=普通用户,2=会员,3=超级会员
    public bool IsVipExpired { get; set; } // 会员是否过期
}

// Controller代码
public ActionResult UserCenter()
{
    var user = new UserInfo
    {
        UserName = "张三",
        UserLevel = 2,
        IsVipExpired = false
    };
    return View(user);
}

Razor 视图中使用@if:

html 复制代码
@model UserInfo <!-- 声明视图模型 -->

<div class="user-center">
    <h2>欢迎您:@Model.UserName</h2>
    
    <!-- 基础@if判断 -->
    @if (Model.UserLevel == 1)
    {
        <p>您是【普通用户】,可享受基础权益</p>
    }
    <!-- 多条件@else if -->
    else if (Model.UserLevel == 2 && !Model.IsVipExpired)
    {
        <p>您是【有效会员】,可享受免运费+9折优惠</p>
    }
    else if (Model.UserLevel == 2 && Model.IsVipExpired)
    {
        <p>您的会员已过期,<a href="/Vip/Recharge">点击续费</a></p>
    }
    <!-- 兜底@else -->
    else
    {
        <p>您是【超级会员】,可享受免运费+8折+专属客服</p>
    }
</div>

2.2 嵌套 @if(复杂条件判断)

html 复制代码
@model UserInfo

<div class="user-gift">
    @if (Model.UserLevel >= 2)
    {
        <p>会员专属福利:</p>
        <!-- 嵌套if -->
        @if (Model.IsVipExpired)
        {
            <span>续费后可领取50元优惠券</span>
        }
        else
        {
            <span>本月可领取2张无门槛优惠券</span>
        }
    }
</div>

2.3 生活类比:奶茶店点单逻辑

@if的逻辑完全对应奶茶店的点单规则:

1.先判断 "是否是会员"(UserLevel >=2)→ 会员有折扣;

2.再判断 "会员是否过期"(IsVipExpired)→ 过期提示续费,未过期送小料;

3.非会员(UserLevel=1)→ 无折扣无赠品。

2.4 @if 高频踩坑点(附解决方案)

踩坑点 错误原因 解决方案
缺少@符号 写成if (Model.UserLevel ==1),引擎识别为 HTML 文本 必须以@开头:@if (Model.UserLevel ==1)
花括号{}缺失 / 错位 多行逻辑未加花括号,或花括号嵌套不匹配 无论逻辑多少行,都加上花括号;嵌套时缩进对齐
Null 引用异常 判断Model.UserName == "张三"但 Model 为 null 先判断 Model 是否为空:@if (Model != null && Model.UserName == "张三") 逻辑运算符混用 把&&写成&,写成 条件判断用短路运算符&&/,避免位运算&/
忘记闭合 HTML 标签 if 块内打开 但未闭合 每个 if 块内的 HTML 标签必须成对闭合,嵌套时检查层级

小节

@if的核心是 "根据条件执行不同的渲染逻辑",就像生活中 "按规则做选择",只要注意@符号、Null 判断和语法格式,就能避免 80% 的错误。

三、核心语法 2:@foreach 循环遍历 ------ 像生活中 "批量处理重复事务"

@foreach用于遍历集合(List / 数组 / 字典等),批量渲染重复的 UI 内容,是开发中 "列表渲染" 的核心语法。

3.1 基础语法(代码示例)

先定义后端传递的集合模型:

csharp 复制代码
// 商品模型
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public bool IsOnSale { get; set; } // 是否打折
}

// Controller代码
public ActionResult ProductList()
{
    var products = new List<Product>
    {
        new Product { Id = 1, Name = "小米14", Price = 4299, IsOnSale = true },
        new Product { Id = 2, Name = "华为Mate60", Price = 5999, IsOnSale = false },
        new Product { Id = 3, Name = "iPhone15", Price = 5999, IsOnSale = true }
    };
    return View(products);
}

Razor 视图中使用@foreach遍历商品列表:

html 复制代码
@model List<Product> <!-- 声明集合模型 -->

<h2>商品列表</h2>
<table border="1" cellpadding="8">
    <tr>
        <th>商品ID</th>
        <th>商品名称</th>
        <th>价格</th>
        <th>状态</th>
    </tr>
    <!-- 遍历商品集合 -->
    @foreach (var product in Model)
    {
        <tr>
            <td>@product.Id</td>
            <td>@product.Name</td>
            <td>@product.Price.ToString("C")</td>
            <!-- 循环内嵌套if判断 -->
            <td>
                @if (product.IsOnSale)
                {
                    <span style="color: red;">限时折扣</span>
                }
                else
                {
                    <span>原价销售</span>
                }
            </td>
        </tr>
    }
</table>

3.2 嵌套 @foreach(复杂列表)

比如遍历 "用户列表 + 每个用户的订单列表":

csharp 复制代码
// 订单模型
public class Order
{
    public int OrderId { get; set; }
    public decimal Amount { get; set; }
}

// 带订单的用户模型
public class UserWithOrder
{
    public string UserName { get; set; }
    public List<Order> Orders { get; set; }
}

// Controller传递数据
public ActionResult UserOrderList()
{
    var userOrders = new List<UserWithOrder>
    {
        new UserWithOrder
        {
            UserName = "张三",
            Orders = new List<Order> { new Order { OrderId = 1001, Amount = 299 }, new Order { OrderId = 1002, Amount = 599 } }
        },
        new UserWithOrder
        {
            UserName = "李四",
            Orders = new List<Order> { new Order { OrderId = 1003, Amount = 1299 } }
        }
    };
    return View(userOrders);
}

Razor 视图嵌套遍历:

html 复制代码
@model List<UserWithOrder>

<h2>用户订单列表</h2>
@foreach (var user in Model)
{
    <div class="user-order">
        <h3>@user.UserName 的订单</h3>
        <ul>
            <!-- 嵌套遍历订单 -->
            @foreach (var order in user.Orders)
            {
                <li>订单ID:@order.OrderId | 金额:@order.Amount.ToString("C")</li>
            }
        </ul>
    </div>
}

3.3 生活类比:快递员派件逻辑

@foreach的逻辑对应快递员派件:

快递员拿到 "包裹集合"(对应后端传递的 List);

循环遍历每个包裹(foreach (var package in packages));

对每个包裹,根据地址(嵌套循环 /if)送到对应的小区 / 楼层;

所有包裹派完,循环结束。

3.4 @foreach 高频踩坑点(附解决方案)

踩坑点 错误原因 解决方案
遍历 Null 集合 Model 为 null 时执行@foreach (var item in Model) 先判断集合是否为空:@if (Model != null && Model.Any()) { foreach(...) } else { 暂无数据 }
遍历中修改集合 遍历过程中执行Model.Add(item)/Model.Remove(item) 遍历不可变集合(如ToList()):@foreach (var item in Model.ToList()),或先复制集合再遍历
嵌套循环性能差 多层嵌套遍历大数据集合,页面渲染慢 后端提前处理数据(如分页、预加载);前端加懒加载;避免 3 层以上嵌套
忘记@符号 写成foreach (var item in Model),引擎识别为 HTML 必须以@开头:@foreach (var item in Model)
模型类型不匹配 后端传Array,视图声明List,遍历时报错 统一模型类型,或转换类型:@foreach (var item in Model as List)

小节

@foreach的核心是 "批量处理重复的 UI 渲染",就像生活中 "批量处理重复事务",重点注意 "空集合判断" 和 "遍历不可变",能大幅减少异常。

四、@if/@foreach 执行流程(可视化流程图)

4.1 @if 条件判断执行流程









Razor引擎解析 if
判断条件是否为true?
执行if块内的C#+HTML代码
是否有 else if?
判断 else if条件
执行 else if块代码
是否有 else?
执行 else块代码
条件判断结束

4.2 @foreach 循环遍历执行流程







Razor引擎解析 foreach
判断集合是否为null?
渲染 暂无数据 提示
集合是否有元素?
获取第一个元素
执行foreach块内的C#+HTML代码
是否有下一个元素?
循环遍历结束

五、实战案例:综合使用 @if+@foreach(商城订单列表)

html 复制代码
@model List<OrderInfo> <!-- 订单信息模型 -->

<style>
    .order-item { margin: 10px 0; padding: 10px; border: 1px solid #eee; }
    .status-paid { color: green; }
    .status-unpaid { color: red; }
</style>

<h2>我的订单列表</h2>

<!-- 先判断订单集合是否为空 -->
@if (Model == null || !Model.Any())
{
    <p>您暂无订单,快去下单吧~</p>
}
else
{
    <!-- 遍历订单列表 -->
    @foreach (var order in Model)
    {
        <div class="order-item">
            <h4>订单编号:@order.OrderNo</h4>
            <p>下单时间:@order.CreateTime.ToString("yyyy-MM-dd HH:mm")</p>
            <p>订单金额:@order.Amount.ToString("C")</p>
            <!-- 判断订单状态 -->
            <p>订单状态:
                @if (order.Status == 1)
                {
                    <span class="status-unpaid">待支付</span>
                    <button>立即支付</button>
                }
                else if (order.Status == 2)
                {
                    <span class="status-paid">已支付</span>
                    <button>查看物流</button>
                }
                else if (order.Status == 3)
                {
                    <span>已完成</span>
                    <button>评价商品</button>
                }
                else
                {
                    <span>已取消</span>
                }
            </p>
        </div>
    }
}

<!-- 订单信息模型(后端定义) -->
@*
public class OrderInfo
{
    public string OrderNo { get; set; } // 订单编号
    public DateTime CreateTime { get; set; } // 下单时间
    public decimal Amount { get; set; } // 订单金额
    public int Status { get; set; } // 1=待支付,2=已支付,3=已完成,4=已取消
}
*@

六、结尾互动

以上就是 Razor 视图引擎中@if和@foreach的核心用法和避坑指南,希望能帮到你~

💬 互动提问:

1.你在使用@if/@foreach时遇到过哪些奇葩问题?

2.有没有自己总结的 "独家避坑技巧"?

欢迎在评论区留言交流,我会一一回复~如果觉得本文有用,别忘了点赞 + 收藏,后续还会更新 Razor 视图引擎的其他核心语法!
核心知识点总结

1.@是 Razor 的 "模式切换开关",所有 C# 逻辑(if/foreach)必须以@开头;

2.@if重点注意 Null 判断、花括号完整性和逻辑运算符使用,核心是 "条件分支渲染";

3.@foreach重点注意空集合判断、禁止遍历中修改集合,核心是 "批量重复渲染";

4.综合使用时,先判断集合是否为空,再遍历,遍历中嵌套 if 判断状态,是最常用的实战写法。

相关推荐
pangtao20252 小时前
【瑞萨RA × Zephyr评测】看门狗
java·后端·spring
码界奇点2 小时前
基于Spring Cloud与Vue.js的微服务前后端分离系统设计与实现
vue.js·后端·spring cloud·微服务·毕业设计·源代码管理
huatian52 小时前
Rust 语法整理
开发语言·后端·rust
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于Springboot的球场管理平台的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
BIBI20493 小时前
Windows 上配置 Nacos Server 3.x.x 使用 MySQL 5.7
java·windows·spring boot·后端·mysql·nacos·配置
IT_陈寒3 小时前
Redis高频踩坑实录:5个不报错但会导致性能腰斩的'隐秘'配置项
前端·人工智能·后端
CoolerWu3 小时前
2025 · 我与 AI / Vibe Coding 的一年
前端·后端
不思念一个荒废的名字3 小时前
【黑马JavaWeb+AI知识梳理】Web后端开发06 - SpringBoot原理篇
spring boot·后端
AC赳赳老秦3 小时前
DeepSeek-Coder vs Copilot:嵌入式开发场景适配性对比实战
java·前端·后端·struts·mongodb·copilot·deepseek