核心思想:关注点分离

无论使用哪种技术,现代 Web 开发的核心思想都是关注点分离

asp.net网页布局代码
(图片来源网络,侵删)
  • HTML (结构): 定义网页的内容和骨架。
  • CSS (表现): 定义网页的样式、颜色、布局和视觉效果。
  • C# (逻辑): 处理数据、用户交互、服务器端逻辑。

ASP.NET 提供了强大的框架来将这三者优雅地结合起来。


ASP.NET Web Forms (传统方式)

Web Forms 采用的是控件事件驱动的模型,开发者通过拖拽控件(如 Panel, Table, div)来构建页面布局,并通过 C# 代码(如 Page_Load, Button_Click 事件)来处理逻辑。

布局方式:母版页

母版页是 Web Forms 中实现统一布局最核心的技术,它定义了所有页面的公共结构(如头部、导航、页脚),而内容页则只需填充具体内容。

Site.Master (母版页文件) 这个文件包含了通用的 HTML 结构和服务器端控件 ContentPlaceHolder

asp.net网页布局代码
(图片来源网络,侵删)
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="MyWebApp.SiteMaster" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head runat="server">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><%: Page.Title %> - 我的 ASP.NET 应用</title>
    <asp:PlaceHolder runat="server">
        <%: Scripts.Render("~/bundles/modernizr") %>
    </asp:PlaceHolder>
    <webopt:bundlereference runat="server" path="~/Content/css" />
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
    <form runat="server">
        <asp:ScriptManager runat="server">
            <Scripts>
                <%-- 为了获得最佳性能,请 Development 中禁用 ScriptBundle。 --%>
                <%-- 有关详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=615859。 --%>
                <asp:ScriptReference Name="jquery" />
                <asp:ScriptReference Name="bootstrap" />
            </Scripts>
        </asp:ScriptManager>
        <!-- 导航栏 -->
        <nav class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" runat="server" href="~/">应用名称</a>
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li><a runat="server" href="~/">首页</a></li>
                        <li><a runat="server" href="~/About.aspx">lt;/a></li>
                        <li><a runat="server" href="~/Contact.aspx">联系方式</a></li>
                    </ul>
                </div>
            </div>
        </nav>
        <!-- 主要内容区域 -->
        <div class="container body-content">
            <!-- 
                这是关键!内容页将把内容放在这里。
                ContentPlaceHolderID 必须与内容页的 Content 控件的 ID 匹配。
            -->
            <asp:ContentPlaceHolder ID="MainContent" runat="server">
            </asp:ContentPlaceHolder>
            <hr />
            <footer>
                <p>&copy; <%: DateTime.Now.Year %> - 我的 ASP.NET 应用</p>
            </footer>
        </div>
    </form>
</body>
</html>

About.aspx (内容页文件) 这个文件只需要继承母版页,并用 <asp:Content> 标签填充特定区域。

<%@ Page Title="quot; Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="MyWebApp.About" %>
<!-- 
    此 Content 控件的 ContentPlaceHolderID 必须与母版页中定义的 ID 匹配。
    只有这个区域的内容是唯一的,其他部分(如导航、页脚)都来自母版页。
-->
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%: Title %></h2>
    <p>此应用程序示例展示了 ASP.NET Web Forms 的基本布局功能。</p>
</asp:Content>

优点

  • 快速开发:通过拖拽控件和事件模型,可以快速构建应用。
  • 状态管理: ViewState 等机制简化了状态管理。
  • 开发模型熟悉:对 Windows Forms 开发者非常友好。

缺点

  • 视图状态:ViewState 会导致生成的 HTML 体积庞大,影响性能。
  • 控件抽象:服务器端控件有时会生成复杂的 HTML,难以精确控制。
  • 与现代前端框架集成困难:React, Vue 等框架更倾向于直接操作 DOM,与 Web Forms 的模型有一定冲突。

ASP.NET Core (现代方式)

ASP.NET Core 是一个跨平台、高性能的框架,它更开放,可以与任何前端技术栈(包括 Razor Pages, MVC, Blazor, React, Angular, Vue 等)无缝集成,布局主要依赖于 Razor 语法布局页

布局方式:_Layout.cshtml

这与 Web Forms 的母版页概念非常相似,但更加灵活和轻量。

/Views/Shared/_Layout.cshtml (布局页文件)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />@ViewData["Title"] - MyASPNETCoreApp</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-dark bg-dark border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MyASPNETCoreApp</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Index">首页</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-light" asp-area="" asp-controller="Home" asp-action="Privacy">隐私</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            <!-- 
                这是关键!@RenderBody() 是一个占位符。
                具体的视图页面(如 Index.cshtml)的内容将被渲染在这里。
            -->
            @RenderBody()
        </main>
    </div>
    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2025 - MyASPNETCoreApp
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    <!-- 
        如果在某个页面需要额外引入脚本,可以在该页面使用 @section Scripts 来覆盖这里的内容。
    -->
    @RenderSection("Scripts", required: false)
</body>
</html>

/Views/Home/Index.cshtml (视图文件) 这个文件继承布局页,并使用 @section 来定义额外的内容。

@{
    ViewData["Title"] = "首页";
}
<div class="text-center">
    <h1 class="display-4">欢迎使用 ASP.NET Core</h1>
    <p>了解如何<a href="https://docs.microsoft.com/aspnet/core">构建 Web 应用程序</a>。</p>
</div>
@section Scripts {
    <!-- 只有这个页面需要的脚本可以放在这里 -->
    <script>
        console.log("这是首页特有的脚本。");
    </script>
}

优点

  • 高性能:没有 ViewState,生成干净的 HTML。
  • 极度灵活:可以轻松集成任何前端库和框架。
  • 开放标准:基于 HTML, CSS, JavaScript 和 Razor,易于学习和掌握。
  • 跨平台:可以在 Windows, Linux, macOS 上运行。

现代前端框架 + ASP.NET Core API (前后端分离)

这是目前大型企业和现代应用的主流架构,ASP.NET Core 只负责提供数据接口(API),而前端使用 React, Angular, Vue 等框架来构建用户界面。

布局方式:前端框架自身 + CSS Grid/Flexbox

在这种情况下,布局完全由前端技术负责,ASP.NET Core 的角色是提供数据。

ASP.NET Core API 控制器 这个 C# 代码只负责返回 JSON 数据。

// Controllers/ProductsController.cs
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    public ActionResult<IEnumerable<Product>> Get()
    {
        var products = new List<Product>
        {
            new Product { Id = 1, Name = "笔记本电脑", Price = 9999 },
            new Product { Id = 2, Name = "无线鼠标", Price = 199 }
        };
        return products;
    }
}
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

前端布局代码 (以 React 为例) 前端通过 API 获取数据,然后使用 JSX 和 CSS (如 Flexbox, Grid) 来渲染布局。

// src/components/ProductList.js
import React, { useState, useEffect } from 'react';
import './ProductList.css'; // 对应的 CSS 文件
function ProductList() {
    const [products, setProducts] = useState([]);
    const [loading, setLoading] = useState(true);
    useEffect(() => {
        // 从 ASP.NET Core API 获取数据
        fetch('/api/products')
            .then(response => response.json())
            .then(data => {
                setProducts(data);
                setLoading(false);
            })
            .catch(error => {
                console.error('Error fetching products:', error);
                setLoading(false);
            });
    }, []); // 空依赖数组表示只在组件挂载时执行一次
    if (loading) {
        return <div>加载中...</div>;
    }
    return (
        <div className="product-list-container">
            <h1>产品列表</h1>
            {/* 使用 CSS Flexbox 进行布局 */}
            <div className="product-grid">
                {products.map(product => (
                    <div key={product.id} className="product-card">
                        <h3>{product.name}</h3>
                        <p>¥ {product.price.toFixed(2)}</p>
                    </div>
                ))}
            </div>
        </div>
    );
}
export default ProductList;

ProductList.css (对应的 CSS 布局)

.product-list-container {
    padding: 20px;
}
.product-grid {
    display: flex; /* 使用 Flexbox */
    flex-wrap: wrap; /* 允许项目换行 */
    gap: 20px; /* 项目之间的间距 */
    justify-content: center; /* 水平居中 */
}
.product-card {
    border: 1px solid #ccc;
    border-radius: 8px;
    padding: 16px;
    width: 200px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    text-align: center;
    transition: transform 0.2s;
}
.product-card:hover {
    transform: translateY(-5px);
}

优点

  • 职责清晰:后端专注数据和业务逻辑,前端专注用户界面和交互。
  • 技术栈独立:团队可以自由选择最适合的前端技术,且可以独立开发、测试和部署。
  • 最佳用户体验:可以构建高度交互和响应式的单页应用。
  • 可扩展性强:同一个 API 可以服务于 Web 端、移动 App (React Native, Flutter) 等多个客户端。

总结与选择建议

特性 ASP.NET Web Forms ASP.NET Core (Razor Pages/MVC) ASP.NET Core + 前端框架
核心布局技术 母版页 _Layout.cshtml 前端框架 (React/Vue等) + CSS
开发模型 事件驱动、服务器端控件 MVC / Razor Pages / Blazor RESTful API + 前端框架
HTML 控制 中等(受控件限制) 高(直接写 HTML) 极高(完全控制)
与现代前端集成 困难 容易 无缝集成
性能 较低(ViewState) 非常高
适用场景 维护旧项目、快速 CRUD 应用 中小型网站、Web 应用、企业级后端 现代 Web 应用、SPA、大型项目

如何选择?

  • 如果你在维护一个旧的 ASP.NET Web Forms 项目:继续使用 Web Forms 和母版页。
  • 如果你要开始一个新的、中型的 Web 项目,且希望快速开发:选择 ASP.NET Core (Razor Pages 或 MVC),使用 _Layout.cshtml 进行布局,这是目前最通用、最平衡的选择。
  • 如果你要构建一个现代化的、交互性强的单页应用,或者项目规模很大,前后端团队分离:选择 ASP.NET Core + 前端框架 的前后端分离模式,这是大型企业和追求最佳用户体验项目的首选。