首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

使用 C# 與 ASP.NET 構建 Web 應用程序:組件化架構、數據綁定與存儲過程最佳實踐

     編輯:關於C語言

歷史背景與現代視角

本文源自 ASP.NET 1.x / .NET Framework 1.0 時代 (Web Forms、.aspx、內聯代碼、`csc.exe` 命令行編譯)。**現代開發請直接使用 ASP.NET Core + Razor Pages / MVC / Minimal APIs + Entity Framework Core**。本文保留為架構演進參考,核心思想 (分層、組件化、參數化查詢、數據綁定) 至今有效。

經典三層架構落地


┌─────────────────────────────────────┐
│       Presentation Layer (UI)       │  ← Default.aspx, ProductList.aspx
│   (Web Forms / ASPX + CodeBehind)   │
└──────────────┬──────────────────────┘
               │ 僅調用業務組件
┌──────────────▼──────────────────────┐
│      Business Logic Layer (BLL)     │  ← CommerceDotNet.dll
│  Category.cs, Product.cs (組件)     │
└──────────────┬──────────────────────┘
               │ 僅調用數據訪問 / 存儲過程
┌──────────────▼──────────────────────┐
│       Data Access Layer (DAL)       │  ← 存儲過程
│   SQL Server + Stored Procedures    │
└─────────────────────────────────────┘

業務組件開發 (Class Library → DLL)

命名空間與類設計


// CategoryDB.cs
namespace CommerceDotNet {
    using System.Data;
    using System.Data.SqlClient;
    using System.Configuration;

    public class Categories {
        public DataSet CategoryList() {
            using (var conn = new SqlConnection(
                ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString))
            using (var cmd = new SqlCommand("sp_GetCategories", conn))
            using (var da = new SqlDataAdapter(cmd)) {
                cmd.CommandType = CommandType.StoredProcedure;
                var ds = new DataSet();
                da.Fill(ds);
                return ds;
            }
        }
    }
}

// ProductDB.cs
namespace CommerceDotNet {
    public class Products {
        public DataSet ProductsList(int categoryId) {
            using (var conn = new SqlConnection(...))
            using (var cmd = new SqlCommand("sp_GetProductsByCategory", conn))
            using (var da = new SqlDataAdapter(cmd)) {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@CategoryId", categoryId);
                var ds = new DataSet();
                da.Fill(ds);
                return ds;
            }
        }
    }
}

命令行編譯為組件 (歷史方式)


csc /target:library /out:bin/CommerceDotNet.dll /reference:System.Data.dll \
    CategoryDB.cs ProductDB.cs

現代專案:`dotnet build` 輸出 DLL,NuGet 管理依賴,`project.json` / `.csproj` 替代命令行參數。

ASPX 頁面數據綁定

Default.aspx — 類別列表


<%@ Page Language="C#" %>
<%@ Import Namespace="CommerceDotNet" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Collections" %>





    

產品類別

<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>

ProductList.aspx — 產品列表 (帶參數)





    
        
        
    

核心最佳實踐 (跨時代有效)

原則經典做法現代對應
**參數化查詢**`cmd.Parameters.AddWithValue("@Id", id)`EF Core 參數化 / Dapper 參數化 / 原生 `SqlParameter`
**存儲過程封裝業務邏輯**T-SQL `sp_GetProductsByCategory`視複雜度決定:EF Core LINQ / 存儲過程 / View / Function
**連接池與 using**`using (var conn = new SqlConnection())`EF Core `DbContext` 池化 / `SqlConnection` 池化 (預設開啟)
**分層解耦**UI → BLL DLL → SPController/Service/Repository 或 Minimal API + MediatR
**數據綁定模板**`<%# Eval("Field") %>` / `DataBinder.Eval`Razor `@item.Field` / Blazor `@item.Field` / Vue/React Props
**配置分離**`Web.config` ```appsettings.json` + `IConfiguration` + User Secrets / Key Vault

存儲過程範例 (SQL Server)


CREATE PROCEDURE sp_GetCategories
AS
SELECT CategoryId, CategoryName, Description FROM Categories ORDER BY CategoryName;

CREATE PROCEDURE sp_GetProductsByCategory
    @CategoryId INT
AS
SELECT ProductId, ProductName, UnitPrice, UnitsInStock 
FROM Products 
WHERE CategoryId = @CategoryId AND Discontinued = 0
ORDER BY ProductName;

從經典遷移到現代:關鍵對照


// 經典:DataSet + DataTable + DefaultView
DataSet ds = bll.GetData();
grid.DataSource = ds.Tables[0].DefaultView;
grid.DataBind();

// 現代 (EF Core + Razor Pages):
public class IndexModel : PageModel {
    private readonly AppDbContext _db;
    public List Products { get; set; }
    public async Task OnGetAsync(int categoryId) {
        Products = await _db.Products
            .Where(p => p.CategoryId == categoryId && !p.Discontinued)
            .OrderBy(p => p.Name)
            .ToListAsync();
    }
}
// Razor 頁面
@foreach (var p in Model.Products) {
    @p.Name@p.Price.ToString("C")
}

結語

雖然 Web Forms、DataSet、內聯腳本、命令行編譯已成歷史,但**分層架構、參數化查詢、存儲過程封裝、聲明式數據綁定、配置外部化**這些核心工程思想穿越版本長存。理解經典有助於洞察現代框架設計初衷,避免重複造輪子。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved