權限與靜態檔控制改進:

- 修正 admin 目錄預設頁路由,避免 403.14 與不必要的延遲重導
- 停用未使用的 Sites 多站點初始化,減少應用程式啟動成本
- 修正 Response.Redirect 後未 return 的流程,避免 1.8 分鐘超時
- 將資料庫 Connection Timeout 降為 10 秒,加速失敗回應
- 將 runAllManagedModulesForAllRequests 設為 false,讓 JS/CSS 等靜態檔案直接由 IIS 回應
This commit is contained in:
2025-11-12 20:45:34 +08:00
parent ae09a6f487
commit b04c07a5eb
8 changed files with 46 additions and 262 deletions

View File

@@ -18,6 +18,8 @@ public class RouteConfig
* */
public static void RegisterRoutes(RouteCollection routes)
{
// Web Forms 專案不使用路由忽略
// 靜態檔案效能優化改在 web.config 的 <handlers> 和 <modules> 中設定
//routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.MapRoute(
// name: "thumb",

View File

@@ -43,11 +43,15 @@ public static class Sites
public static double MaxAge = 3600 * 24 * 365;
static Sites()
{
// 多站點功能暫時停用,未來有需要再啟用
// 如需啟用,取消下方註解即可
/*
JObject o=get_jsonfile(@"sites\sites-config.json");
sites = o["sites"].ToObject<List<Site>>();
resource = o["resource"].ToObject<SiteResource>();
//resource.Add(new KeyValuePair<string, string>("assets", "assets"));
//resource.Add(new KeyValuePair<string, string>("config", "config"));
*/
}
private static JObject get_jsonfile(string jsonfile)
{

View File

@@ -25,7 +25,8 @@ public class FilesController : ApiController
[Route("upload/{*url}")]
public async Task<HttpResponseMessage> get_upload(string url)
{
var path = Sites.get_url("upload", url);
// 改用標準路徑(原本使用 Sites 多站點功能,目前已停用)
var path = HttpContext.Current.Server.MapPath($"~/upload/{url}");
if (!System.IO.File.Exists(path))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
@@ -38,7 +39,7 @@ public class FilesController : ApiController
response.Headers.CacheControl = new CacheControlHeaderValue()
{
Public = true,
MaxAge = TimeSpan.FromSeconds(Sites.MaxAge)
MaxAge = TimeSpan.FromSeconds(Sites.MaxAge) // MaxAge 常數仍可使用
};
return response;

View File

@@ -385,12 +385,14 @@ namespace MyWeb
if (!admin.isLoign())
{
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=A1");
return; // 立即終止,避免繼續執行後面的資料庫查詢
}
else
{
if (admin.info.login_ip != admin.MyIP)
{
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=E");
return; // 立即終止
}
foreach (string key in HttpContext.Current.Request.Form)
@@ -1023,12 +1025,14 @@ namespace MyWeb
if (!admin.isLoign())
{
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=A2");
return; // 立即終止
}
else
{
if (admin.info.login_ip != admin.MyIP)
{
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=E");
return; // 立即終止
}
this.Page.MasterPageFile = "~/admin/Templates/TBS5ADM001/MasterPage.master";
//this.Theme = "Theme1";

View File

@@ -34,11 +34,13 @@ namespace MyWeb
if (!admin.isLoign())
{
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=A3");
return; // 立即終止,避免繼續執行後面的資料庫查詢
}
if (admin.info.login_ip != admin.MyIP)
{
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=E");
return; // 立即終止
}
//檢查是否被停權
@@ -60,12 +62,13 @@ namespace MyWeb
{
sqlConn.Close(); sqlConn.Dispose();
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=B");
//帳號停權
return; //帳號停權,立即終止
}
if (SingleIn == "Y" && dt.Rows[0]["login_code"].ToString() != admin.info.login_code)
{
sqlConn.Close(); sqlConn.Dispose();
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=C"); //不允許同一個帳號多重登入
return; // 立即終止
}
}
else
@@ -73,6 +76,7 @@ namespace MyWeb
//帳號不存在
sqlConn.Close(); sqlConn.Dispose();
HttpContext.Current.Response.Redirect("~/admin/index.aspx?msg=D");
return; // 立即終止
}
}
catch (Exception ex)

View File

@@ -13,7 +13,8 @@
{
// Code that runs on application startup
// run static constructor
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(Sites).TypeHandle);
// Sites 多站點功能暫時停用,未來有需要再啟用
//System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(Sites).TypeHandle);
//註冊webapi
GlobalConfiguration.Configure(WebApiConfig.Register);
//GlobalConfiguration.Configuration.Services.Replace(

View File

@@ -1,255 +0,0 @@
using System;
using System.Web.UI.WebControls;
using System.Data;
using System.Linq;
using System.Collections.Generic;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Text;
using System.Globalization;
using Model;
public partial class admin_order_print : MyWeb.function
{
private Model.ezEntities _db = new Model.ezEntities();
public string body_class = "tablet-l";
protected void Page_Load(object sender, EventArgs e)
{
string bclass = Request["class"];
if (!String.IsNullOrEmpty(bclass))
{
body_class= bclass;
}
if (!IsPostBack)
{
if (!isStrNull(Request["num"]) && !isStrNull(Request["detail"]))
{
int _detail = Val(Request["detail"]);
var orderItem = _db.pro_order_detail.AsEnumerable().Where(q => q.num == _detail).FirstOrDefault();
int _num = Val(Request["num"]);
var qry = _db.files.AsEnumerable();
var prod = qry.Where(q => q.num == _num).FirstOrDefault();
if (prod != null && orderItem !=null)
{
string _word = prod.word; //格式_列印檔html
string file_cuz_column = prod.customize_data ?? "";
//格式->品項->活動->信眾->報名->報名明細
//上至下層依序讀入各自定義欄位:名稱及值
List<string> newStrList = new List<string>(); //參數集合((名稱及值​
if (!string.IsNullOrEmpty(file_cuz_column))
{
proCuzData(newStrList, file_cuz_column);
}
if (orderItem.actItem_num.HasValue && !string.IsNullOrEmpty(orderItem.actItem.customize_data))
{
proCuzData(newStrList, orderItem.actItem.customize_data);
}
if (orderItem.pro_order.activity_num.HasValue && !string.IsNullOrEmpty(orderItem.pro_order.activity.customize_data))
{
proCuzData(newStrList, orderItem.pro_order.activity.customize_data);
}
//if (orderItem.f_num.HasValue && !string.IsNullOrEmpty(orderItem.follower.customize_data))
if (orderItem.pro_order.f_num.HasValue && !string.IsNullOrEmpty(orderItem.pro_order.follower.customize_data))//訂單主黨的姓名/名稱?
{
proCuzData(newStrList, orderItem.pro_order.follower.customize_data);
}
if (!string.IsNullOrEmpty(orderItem.pro_order.customize_data))
{
proCuzData(newStrList, orderItem.pro_order.customize_data);
}
if (!string.IsNullOrEmpty(orderItem.customize_data))
{
proCuzData(newStrList, orderItem.customize_data);
}
//string detail_data = orderItem.customize_data ?? ""; //訂單明細的自訂欄位
string detail_data = newStrList.Count > 0 ? string.Join("\r\n", newStrList) : "";//參數集合((名稱及值​
string[] k = detail_data.Split('$');
//取代
for (int i=0; i < k.Length; i++)
{
if (!isStrNull(k[i]))
{
string[] _v = k[i].Split(':');
_word = _word.Replace("{$"+ _v [0]+ "}", _v[1].Trim());
}
}
//加入固定欄位變數定義
//日期
string[] _type = { "zh", "min", "lunar" };
_word = _word.Replace("{pro_order.up_time}", !isStrNull(orderItem.pro_order.up_time)? proDateStr(orderItem.pro_order.up_time.Value,""):"");
foreach (var tt in _type)
{
_word = _word.Replace("{pro_order.up_time." + tt + "}", !isStrNull(orderItem.pro_order.up_time) ? proDateStr(orderItem.pro_order.up_time.Value, tt) : "");
}
_word = _word.Replace("{activity.startDate_solar}", !isStrNull(orderItem.pro_order.activity.startDate_solar) ? proDateStr(orderItem.pro_order.activity.startDate_solar.Value, "") : "");
foreach (var tt in _type)
{
_word = _word.Replace("{activity.startDate_solar." + tt + "}", !isStrNull(orderItem.pro_order.activity.startDate_solar) ? proDateStr(orderItem.pro_order.activity.startDate_solar.Value, tt) : "");
}
_word = _word.Replace("{activity.endDate_solar}", !isStrNull(orderItem.pro_order.activity.endDate_solar) ? proDateStr(orderItem.pro_order.activity.endDate_solar.Value, "") : "");
foreach (var tt in _type)
{
_word = _word.Replace("{activity.endDate_solar." + tt + "}", !isStrNull(orderItem.pro_order.activity.endDate_solar) ? proDateStr(orderItem.pro_order.activity.endDate_solar.Value, tt) : "");
}
//金額
_word = _word.Replace("{pro_order_detail.price}", !isStrNull(orderItem.price) ? ValMoneyCh(orderItem.price.Value) : "");
word.Text = _word;
}
}
else
{
Response.Clear();
Response.StatusCode = 404;
Response.End();
}
}
}
#region
protected void proCuzData(List<string> _column, string this_data)
{
if (!string.IsNullOrWhiteSpace(this_data))
{
string[] _list = this_data.Split('$');
for (int i = 0; i < _list.Length; i++)
{
if (!string.IsNullOrWhiteSpace(_list[i]))
{
string[] _v = _list[i].Split(':');
//比對
bool isExist = false; //參數是否已存在
for (int j = 0; j < _column.Count; j++)
{
string[] _y = _column[j].Split(':');
if ("$" + _v[0] == _y[0])
{
isExist = true;
if (!string.IsNullOrWhiteSpace(_v[1]))
_column[j] = "$" + _list[i];
break;
}
}
if (!isExist)
{
//加入參數
_column.Add("$" + _list[i]);
}
}
}
}
}
#endregion
#region
protected string proDateStr(DateTime date, string type )
{
string txt = "";
if (type == "")
{
txt = date.ToString("yyyy/MM/dd");
}
else if(type == "zh")//西元中文日期
{
//将日期转换成中文显示
string year = date.Year.ToString();
string month = date.Month.ToString("00");
//if (int.Parse(month) < 10) { month = "0" + month; }
string days = date.Day.ToString("00");
//if (int.Parse(days) < 10) { days = "0" + days; }
txt = GetChineseDateNumber2(year, month, days);
}
else if (type == "min")//民國中文日期
{
//轉成民國年
CultureInfo culture = new CultureInfo("zh-TW");
culture.DateTimeFormat.Calendar = new TaiwanCalendar();
string _cul= date.ToString("yyy/MM/dd", culture);
string[] k = _cul.Split('/');
//System.Globalization.TaiwanCalendar tc = new System.Globalization.TaiwanCalendar();
//tc.GetYear(date), tc.GetMonth(date), tc.GetDayOfMonth(date)
if (k.Length == 3)
{
txt = GetChineseDateNumber2(k[0], k[1], k[2]);
}
}
else if (type == "lunar")//民國年農曆日期
{
//轉成農曆年
ChineseLunisolarCalendar chineseDate = new ChineseLunisolarCalendar();
int yy = chineseDate.GetYear(date) - 1911;
int mm = chineseDate.GetMonth(date);
int dd = chineseDate.GetDayOfMonth(date);
txt = GetChineseDateNumber2(yy.ToString(), mm.ToString("00"), dd.ToString("00"));
}
return txt;
}
static string GetChineseDateNumber2(string year, string month, string days)
{
//StringBuilder sb = new StringBuilder();
List<string> sb = new List<string>();
for (int i = 0; i < year.Length; i++)//年转换
{
//sb.Append(GetChineseDateNumber(int.Parse(year[i].ToString())));
sb.Add(GetChineseDateNumber(int.Parse(year[i].ToString())));
}
sb.Add("年");
for (int r = 0; r < month.Length; r++)//月转换
{
sb.Add(GetChineseDateNumber(int.Parse(month[r].ToString())));
}
sb.Add("月");
for (int t = 0; t < days.Length; t++)//日转换
{
sb.Add(GetChineseDateNumber(int.Parse(days[t].ToString())));
}
sb.Add("日");
//return sb.ToString();
return string.Join("", sb);
}
static string GetChineseDateNumber(int dateStr)
{
string[] cns = new string[] {
"零", "一", "二", "三", "四", "五", "六", "七", "八", "九",
"十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九",
"二十", "二十一", "二十二", "二十三", "二十四", "二十五", "二十六", "二十七", "二十八", "二十九",
"三十", "三十一"
};
return cns[dateStr];
}
#endregion
}

View File

@@ -44,8 +44,8 @@
<connectionStrings>
<!--SQL用-->
<!-- -->
<add name="shopConn" providerName="System.Data.SqlClient" connectionString="Data Source=localhost;Initial Catalog=17168erp_t;User ID=17168erp;Password=17168erp;Encrypt=False;TrustServerCertificate=True;Provider=SQLOLEDB;" />
<add name="ezEntities" connectionString="metadata=res://*/App_Code.Model.Model.csdl|res://*/App_Code.Model.Model.ssdl|res://*/App_Code.Model.Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost;Initial Catalog=17168erp_t;User ID=17168erp;Password=17168erp;Encrypt=False;TrustServerCertificate=True;&quot;" providerName="System.Data.EntityClient" />
<add name="shopConn" providerName="System.Data.SqlClient" connectionString="Data Source=localhost;Initial Catalog=17168erp_t;User ID=17168erp;Password=17168erp;Encrypt=False;TrustServerCertificate=True;Provider=SQLOLEDB;Connection Timeout=10;" />
<add name="ezEntities" connectionString="metadata=res://*/App_Code.Model.Model.csdl|res://*/App_Code.Model.Model.ssdl|res://*/App_Code.Model.Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost;Initial Catalog=17168erp_t;User ID=17168erp;Password=17168erp;Encrypt=False;TrustServerCertificate=True;Connection Timeout=10;&quot;" providerName="System.Data.EntityClient" />
<!--SQL用-->
</connectionStrings>
<!--
@@ -110,8 +110,31 @@
<httpRuntime requestValidationMode="2.0" enableVersionHeader="false" />
</system.web>
<system.webServer>
<!-- 設定預設文檔,解決目錄存取問題 (403.14) -->
<!-- 適用於 IIS Express、IIS 根目錄、IIS 虛擬目錄/應用程式 等所有部署情境 -->
<defaultDocument enabled="true">
<files>
<!-- 先移除可能存在的項目,避免重複錯誤 -->
<remove value="index.aspx" />
<remove value="Default.aspx" />
<remove value="default.aspx" />
<remove value="index.htm" />
<remove value="index.html" />
<!-- 然後按優先順序添加 -->
<add value="index.aspx" />
<add value="Default.aspx" />
<add value="index.htm" />
<add value="index.html" />
</files>
</defaultDocument>
<!-- 支援路由有"." https://stackoverflow.com/questions/9273987/asp-net-mvc-url-route-supporting-dot -->
<modules runAllManagedModulesForAllRequests="true" />
<!-- 改為 false 提升靜態檔案效能JS/CSS/圖片直接由 IIS 處理,不走 ASP.NET 管線)-->
<!-- WebAPI 和 ASPX 頁面仍會正常處理 -->
<modules runAllManagedModulesForAllRequests="false">
<!-- 保留 UrlRoutingModule 讓 Web API 路由正常運作 -->
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
<!--修補弱點IIS 目錄列舉-->
<security>
<requestFiltering>