// prov.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
// URL Rewrite 已自動解碼,直接獲取
string provName = Request.QueryString["provname"]; // "北京市"
if (!string.IsNullOrEmpty(provName))
{
// 查詢數據綁定
var cities = AreaService.GetCitiesByProvince(provName);
rptCities.DataSource = cities;
rptCities.DataBind();
}
}
// city.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string provName = Request.QueryString["provname"]; // "北京市"
string cityName = Request.QueryString["cityname"]; // "朝陽區"
// 邏輯處理...
}
Rewrite 規則中 `{UrlEncode:{R:1}}` 確保中文參數正確編碼傳遞給 .aspx 頁面,避免雙重編碼/解碼錯誤。
| 模式 | 匹配示例 | 捕獲組 |
|---|---|---|
| `^([^/]+)[省|市]\.html$` | `/北京市.html`、`/上海市.html` | `{R:1}` = "北京市" |
| `^([^/]+)/([^/]+)\.html$` | `/北京市/朝陽區.html` | `{R:1}`="北京市", `{R:2}`="朝陽區" |
| `^article/([^/]+)-(\d+)\.html$` | `/article/標題-123.html` | `{R:1}`="標題", `{R:2}`="123" |
| 現象 | 原因 | 解決 |
|---|---|---|
| 404 Not Found | 規則未匹配 / 靜態文件衝突 | 檢查正則、添加 StaticFiles 規則優先 |
| 參數亂碼 | 雙重編碼/解碼 | 使用 `{UrlEncode:{R:N}}`、確保頁面 UTF-8 |
| 無限循環重寫 | 規則匹配自身輸出 | 添加 `stopProcessing="true"`、條件排除 .aspx |
| 中文 URL 無法訪問 | IIS 請求過濾/編碼設置 | 請求過濾允許雙重編碼、高位字符 |
// Program.cs
app.MapGet("/{province:chinese}市.html", async (string province, HttpContext ctx) =>
{
// 直接獲得解碼後的中文參數
var cities = await _service.GetCitiesAsync(province);
return Results.View("Province", cities);
});
app.MapGet("/{province:chinese}市/{city:chinese}.html", async (string province, string city) =>
{
var districts = await _service.GetDistrictsAsync(province, city);
return Results.View("City", districts);
});
// 自定義路由約束
public class ChineseConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey,
RouteValueDictionary values, RouteDirection routeDirection)
{
return values[routeKey] is string s && Regex.IsMatch(s, @"^[\u4e00-\u9fa5]+$");
}
}
中文 URL 在偽靜態架構下完全可行,關鍵在於 Rewrite 規則正確編碼傳遞、後台正確解碼接收、靜態資源隔離放行,配合現代路由系統更加優雅強大。