RegisterStartupScript(key, script) 等价于body.onload=f(){}里的内容?!

本文详细对比了 ASP.NET 中 RegisterStartupScript 和 RegisterClientScriptBlock 方法的功能差异,阐述了它们在页面不同位置注册脚本块的特点,并通过实例验证了 RegisterStartupScript 并不等价于 body.onload 中的脚本执行。

关于RegisterClientScriptBlock和RegisterStartupScript的区别,网上很多贴子是这么解释的:

这两个方法唯一的不同之处在于向“何处”注册脚本块。
         RegisterClientScriptBlock(key, script) 在 form开始处(紧接 <form runat="server"> 标识之后)发送脚本块      
         使用场景:               一般不使用DOM元素
         RegisterStartupScript(key, script) 在 form结尾处(在 </form> 标识之前)发送脚本块,在document装载完成后会执行,等价于body.onload=f(){}里的内容
         使用场景:               一般要使用DOM元素,比如:修改dom元素的值等
实验一下,我们发现:
RegisterClientScriptBlock(key, script) 在 form开始处(紧接 <form runat="server"> 标识之后)发送脚本块 
RegisterStartupScript(key, script) 在 form结尾处(在 </form> 标识之前)发送脚本块
这是这两个方法的区别。但问题是:
在 form结尾处(在 </form> 标识之前)发送脚本块,等价于body.onload=f(){}里的内容吗?显然不是啊!
比如,
如果我们的DOM对象放在<form></form>之后,在body.onload中的JS函数,仍然是可以访问的,但放在
RegisterStartupScript(key, script) 仍然无法访问!
 
 
 
比如下面的页面结构:
 
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="1.aspx.cs" Inherits="rent._1" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript">
        function f() {
            alert(document.getElementById("spn1").innerText);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
    </div>
    </form>
    <spn id="spn1">Span Text</spn>
</body>
</html>

用下面的方法扫行f(),JS是无法取得DOM对象spn1的:

protected void Page_Load(object sender, EventArgs e)

        {

            RegisterStartupScript("scr_login", "<script type=\"text/javascript\">f();</script>");

        }

    }

 

 

所以,结论是:

RegisterStartupScript(key, script) 并不等价于body.onload=f(){}
 
 
关于RegisterClientScriptBlock和RegisterStartupScript的区别,只是前者被放在了<form>之后,
 
而后者放了在了</form>之前(能够访问form之前和form之中,但不能访问form之后的DOM对象),仅此而已!
 
 
最后,再讨论一个问题:脚本放在<body onload="f1();">,和放在HTML文档最后面有区别吗?
 
放在<body onload="f1();">中,要等到整个页面所有元素(包括所有图片)都加载完成之后才能执行,这时可以获取到页面上图片的尺寸。
放在HTML最后面,只要html文件加载并解析到最后就能执行,这时可以获取到页面上的元素,却不能获取到页面上图片的尺寸。
Imports System.Data Imports NPOI.HSSF.UserModel Imports NPOI.SS.UserModel Imports System.Collections.Generic Partial Class MIT2_AcceptQuery Inherits System.Web.UI.Page Dim db As SqlDb = New SqlDb() Dim ds As DataSet Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Dim sql = "SELECT DISTINCT 公司編號,公司名稱 FROM MITDEVIL.料號_count" ddlDataSet(pear, sql, "公司名稱", "公司編號") End If End Sub Sub ddlDataSet(ByVal dll As DropDownList, ByVal sql As String, ByVal text As String, ByVal value As String) ds = db.FillDataSet(sql) dll.Items.Clear() dll.DataSource = ds dll.DataTextField = text dll.DataValueField = value dll.DataBind() dll.Items.Insert(0, "") End Sub Protected Sub BTN_search_Click(sender As Object, e As System.EventArgs) Handles BTN_search.Click Dim sql As String = "SELECT 驗收單號 ,驗收序號 ,驗收人員 ,CONVERT(varchar(10),資料日期,111) 資料日期 ," & _ " 廠商編號 ,廠商名稱 ,料號 ,品名規格, 數量, 價格 ,單位 ,幣別 ,備註 ,廠別 ,匯率 ,異動類型 ," & _ " CONVERT(varchar(10),異動日期 ,111) 異動日期 ,集團類別 ,Price_Copy,Money,Date_Price_Copy " & _ " FROM [MITDEVIL].[計劃異動] WHERE 1=1 " If pear.Text = "" Then System.Web.UI.ScriptManager.RegisterStartupScript(UpdatePanel1, GetType(UpdatePanel), "AjaxMsgBox", "alert('請選擇基準公司!');", True) Exit Sub Else sql = sql + " AND 公司編號='" + pear.SelectedItem.Value + "'" End If If part_number.Text <> "" Then sql = sql + " AND 料號='" + part_number.Text + "'" End If If stradate.Value <> "" Then sql = sql + " AND 資料日期 >='" + stradate.Value + "'" End If If enddate.Value <> "" Then sql = sql + " AND 資料日期 <= '" + enddate.Value + "'" End If If createdate.Value <> "" Then sql = sql + " AND convert(char(10),創建日期,111) = convert(char(10),'" + createdate.Value + "',111)" End If sql = sql + " ORDER BY 資料日期 DESC " ViewState("AcceptDT") = db.FillDataSet(sql).Tables(0) GridView1.DataSource = db.FillDataSet(sql) ViewState("sql") = sql GridView1.DataBind() End Sub Protected Sub btn_export_Click(sender As Object, e As System.EventArgs) Handles btn_export.Click Dim arr As New ArrayList Try arr.Add("驗收單號") arr.Add("驗收序號") arr.Add("驗收人員") arr.Add("資料日期") arr.Add("廠商編號") arr.Add("廠商名稱") arr.Add("料號") arr.Add("品名規格") arr.Add("數量") arr.Add("價格") arr.Add("單位") arr.Add("幣別") arr.Add("備註") arr.Add("廠別") arr.Add("匯率") arr.Add("異動類型") arr.Add("異動日期") arr.Add("集團類別") arr.Add("價格冊單價") arr.Add("價格冊幣別") arr.Add("價格冊生效日期") SaveDate(CreateExcel(db.FillDataSet(ViewState("sql")), arr), "驗收單資料.xls") Catch ex As Exception Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "MsgBox", "alert(轉檔失敗,請重試或者聯繫系統負責人');", True) ' Return End Try End Sub Private Function CreateExcel(ByVal ds As DataSet, ByVal arrs As ArrayList) As NPOI.SS.UserModel.IWorkbook Dim workbook As IWorkbook = New NPOI.HSSF.UserModel.HSSFWorkbook() Dim sheet As New ArrayList Dim sheet1 As NPOI.SS.UserModel.ISheet = workbook.CreateSheet(arrs(0)) sheet.Add(sheet1) If arrs.Count = 4 Then Dim sheet4 As NPOI.SS.UserModel.ISheet = workbook.CreateSheet(arrs(3)) sheet.Add(sheet4) End If Dim headstyle As ICellStyle = workbook.CreateCellStyle Dim headfontstyle As HSSFFont = workbook.CreateFont 'Dim textfontstyle As HSSFFont = workbook.CreateFont Dim textstyle As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle2 As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle3 As HSSFCellStyle = workbook.CreateCellStyle Dim textstyle4 As HSSFCellStyle = workbook.CreateCellStyle Dim formact As HSSFDataFormat = workbook.CreateDataFormat Dim arr As New ArrayList With headfontstyle .Boldweight = NPOI.SS.UserModel.FontBoldWeight.Bold End With 'With textfontstyle ' .Boldweight = NPOI.SS.UserModel.FontBoldWeight.Bold ' .Color = NPOI.SS.UserModel.FontColor.Red 'End With With headstyle .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center ' .VerticalAlignment = SS.UserModel.VerticalAlignment.Center '.WrapText = True .SetFont(headfontstyle) .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin End With With textstyle .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin End With With textstyle2 '日期格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin .DataFormat = HSSFDataFormat.GetBuiltinFormat("yyyy/MM/dd") End With With textstyle3 '數值帶千分位格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Right .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin '.DataFormat = HSSFDataFormat.GetBuiltinFormat("G/通用格式") .DataFormat = formact.GetFormat("0.00") End With With textstyle4 '數值格式的 .Alignment = NPOI.SS.UserModel.HorizontalAlignment.Right .BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin .BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin .BorderTop = NPOI.SS.UserModel.BorderStyle.Thin .BorderRight = NPOI.SS.UserModel.BorderStyle.Thin .DataFormat = formact.GetFormat("0") End With arr.Add(textstyle) arr.Add(textstyle2) arr.Add(textstyle3) arr.Add(textstyle4) '開始寫入SHEET1 '创建行 Dim row As NPOI.SS.UserModel.IRow = sheet(0).CreateRow(0) For k As Integer = 0 To arrs.Count - 1 '创建单元格 Dim cell As NPOI.SS.UserModel.ICell = row.CreateCell(k) '设置单元格值 cell.SetCellValue(arrs(k).ToString) cell.CellStyle = headstyle Next For i As Integer = 0 To ds.Tables(0).Rows.Count - 1 '创建行 row = sheet(0).CreateRow(i + 1) For j As Integer = 0 To ds.Tables(0).Columns.Count - 1 '创建单元格 Dim cell As NPOI.SS.UserModel.ICell = row.CreateCell(j) '设置单元格值 'cell.SetCellValue(ds.Tables(0).Rows(i)(field.Item(j).ToString).ToString) ' cell.CellStyle = textstyle SetCellValueByColumnType(row, j, ds.Tables(0).Rows(i)(j), ds.Tables(0).Columns(j), arr) Next Next For i As Integer = 0 To ds.Tables(0).Columns.Count - 1 sheet(0).AutoSizeColumn(i) Next Return workbook End Function Private Sub SetCellValueByColumnType(ByVal myExcelRow As NPOI.SS.UserModel.IRow, ByVal myNewCellIndex As Integer, _ ByVal myValue As Object, ByVal myDataColumn As DataColumn, ByVal arr As ArrayList) If myExcelRow Is Nothing Then Exit Sub If myNewCellIndex < 0 Then Exit Sub If myValue Is Nothing Then Exit Sub If myDataColumn Is Nothing Then Exit Sub Select Case (myDataColumn.DataType.ToString()) Case "System.String" '://字符串类型 myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) Case "System.DateTime" '://日期类型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDateTime(myValue).ToShortDateString) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(1) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Boolean" '://布尔型 If Not IsDBNull(myValue) Then If Convert.ToBoolean(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue("True") Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue("False") End If End If Case "System.Int16", "System.Int32", "System.Int64" '://整型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToInt64(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(3) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Byte" If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToByte(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Decimal" '://浮点型 If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDecimal(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(2) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case "System.Double" If Not IsDBNull(myValue) Then myExcelRow.CreateCell(myNewCellIndex).SetCellValue(Convert.ToDouble(myValue)) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(2) Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End If Case Else myExcelRow.CreateCell(myNewCellIndex).SetCellValue(myValue.ToString().Trim) myExcelRow.GetCell(myNewCellIndex).CellStyle = arr(0) End Select End Sub Private Sub SaveDate(ByVal workbook As NPOI.SS.UserModel.IWorkbook, ByVal ExcelName As String) Dim ms As IO.MemoryStream Try '建立資料流 ms = New IO.MemoryStream() '寫入資料流 workbook.Write(ms) '在頁面輸出資料 Dim filename As String = "attachment;filename=" & HttpUtility.UrlEncode(ExcelName, Encoding.UTF8).ToString() Response.AddHeader("Content-Disposition", filename) Response.BinaryWrite(ms.ToArray()) Catch ex As Exception Finally '釋放資源 If Not ms Is Nothing Then ms.Dispose() ms.Close() End If End Try End Sub Protected Sub GridView1_PageIndexChanging(sender As Object, e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging GridView1.PageIndex = e.NewPageIndex GridView1.DataSource = ViewState("AcceptDT") GridView1.DataBind() End Sub End Cl给gridciew1绑定一个翻页功能
06-21
using System; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.UI; using System.Web.Configuration; namespace WebApplication1 { public partial class WebForm3 : System.Web.UI.Page { private int currentProductId; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { if (!ValidateRequestParameters()) { Response.Redirect("~/Default.aspx"); return; } LoadProductDetails(currentProductId); LoadRelatedProducts(currentProductId); LogPageVisit(currentProductId); } } /// <summary> /// 验证请求参数并获取商品ID /// </summary> private bool ValidateRequestParameters() { if (!int.TryParse(Request.QueryString["id"], out currentProductId)) { ShowErrorMessage("无效的商品ID参数"); return false; } if (currentProductId <= 0) { ShowErrorMessage("商品ID必须为正整数"); return false; } return true; } /// <summary> /// 加载商品详情 /// </summary> private void LoadProductDetails(int productId) { string connString = GetConnectionString(); if (string.IsNullOrEmpty(connString)) { ShowErrorMessage("数据库连接配置错误"); return; } try { using (var conn = new SqlConnection(connString)) { // 获取商品基本信息和图片 string query = @" SELECT p.ProductID, p.ProductName, p.Subtitle, p.Description, p.Price, p.DiscountPrice, p.StockQuantity, p.CategoryID, p.Rating, p.ReviewCount, c.CategoryName, pi.ImagePath, STRING_AGG(pv.VariantName, ', ') AS AvailableVariants FROM Products p INNER JOIN Categories c ON p.CategoryID = c.CategoryID LEFT JOIN ProductImages pi ON p.ProductID = pi.ProductID AND pi.IsDefault = 1 LEFT JOIN ProductVariants pv ON p.ProductID = pv.ProductID WHERE p.ProductID = @ProductID GROUP BY p.ProductID, p.ProductName, p.Subtitle, p.Description, p.Price, p.DiscountPrice, p.StockQuantity, p.CategoryID, p.Rating, p.ReviewCount, c.CategoryName, pi.ImagePath"; using (var cmd = new SqlCommand(query, conn)) { cmd.Parameters.AddWithValue("@ProductID", productId); conn.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { DisplayProductDetails(reader); productContainer.Visible = true; } else { ShowErrorMessage("找不到指定的商品"); } } } } } catch (SqlException sqlEx) { LogError($"SQL错误: {sqlEx.Message}", sqlEx); ShowErrorMessage("数据库连接错误,请稍后再试"); } catch (Exception ex) { LogError($"加载商品信息失败: {ex.Message}", ex); ShowErrorMessage("加载商品信息时出错"); } } /// <summary> /// 显示商品详情到页面控件 /// </summary> private void DisplayProductDetails(SqlDataReader reader) { // 基本信息 ltProductName.Text = HttpUtility.HtmlEncode(reader["ProductName"].ToString()); ltSubtitle.Text = HttpUtility.HtmlEncode(reader["Subtitle"].ToString()); ltCategory.Text = HttpUtility.HtmlEncode(reader["CategoryName"].ToString()); // 价格 decimal price = Convert.ToDecimal(reader["Price"]); ltPrice.Text = price.ToString("C"); if (!Convert.IsDBNull(reader["DiscountPrice"]) && price > Convert.ToDecimal(reader["DiscountPrice"])) { ltDiscountPrice.Text = Convert.ToDecimal(reader["DiscountPrice"]).ToString("C"); } // 库存 int stock = Convert.ToInt32(reader["StockQuantity"]); ltStock.Text = stock.ToString(); ltStockStatus.Text = stock > 0 ? "<span class='text-success'><i class='bi bi-check-circle'></i>有货</span>" : "<span class='text-danger'><i class='bi bi-x-circle'></i>缺货</span>"; // 评分 decimal rating = Convert.ToDecimal(reader["Rating"]); ltRating.Text = GenerateRatingStars(rating); ltReviewCount.Text = reader["ReviewCount"].ToString(); // 图片 string imagePath = reader["ImagePath"]?.ToString() ?? ""; imgProduct.ImageUrl = !string.IsNullOrEmpty(imagePath) ? imagePath : "~/Images/default-product.jpg"; // 描述 ltDescription.Text = HttpUtility.HtmlEncode(reader["Description"].ToString()); // 商品型号 if (!reader.IsDBNull(reader.GetOrdinal("AvailableVariants"))) { ltAvailableVariants.Text = reader["AvailableVariants"].ToString(); } } /// <summary> /// 生成评分星星HTML /// </summary> private string GenerateRatingStars(decimal rating) { int fullStars = (int)rating; bool hasHalfStar = (rating - fullStars) >= 0.5M; int emptyStars = 5 - fullStars - (hasHalfStar ? 1 : 0); return $@" {string.Concat(Enumerable.Repeat("<i class='bi bi-star-fill text-warning'></i>", fullStars))} {(hasHalfStar ? "<i class='bi bi-star-half text-warning'></i>" : "")} {string.Concat(Enumerable.Repeat("<i class='bi bi-star text-warning'></i>", emptyStars))} <span class='ms-2'>{rating:F1}</span>"; } /// <summary> /// 加载相关商品 /// </summary> private void LoadRelatedProducts(int productId) { string connString = GetConnectionString(); if (string.IsNullOrEmpty(connString)) return; try { using (var conn = new SqlConnection(connString)) { // 获取同类别的前4个相关商品 string query = @" SELECT TOP 4 p.ProductID, p.ProductName, p.Price, pi.ImagePath FROM Products p INNER JOIN Categories c ON p.CategoryID = c.CategoryID CROSS APPLY ( SELECT TOP 1 ImagePath FROM ProductImages WHERE ProductID = p.ProductID ORDER BY IsDefault DESC ) pi WHERE p.CategoryID = ( SELECT CategoryID FROM Products WHERE ProductID = @ProductID ) AND p.ProductID <> @ProductID ORDER BY NEWID()"; using (var cmd = new SqlCommand(query, conn)) { cmd.Parameters.AddWithValue("@ProductID", productId); conn.Open(); rptRelatedProducts.DataSource = cmd.ExecuteReader(); rptRelatedProducts.DataBind(); } } } catch (Exception ex) { LogError($"加载相关商品失败: {ex.Message}", ex); } } /// <summary> /// 添加到购物车按钮点击事件 /// </summary> protected void btnAddToCart_Click(object sender, EventArgs e) { if (!ValidateRequestParameters()) return; try { // 获取用户选择的型号 string variant = Request.Form["product_variant"]; // 获取数量 int quantity; if (!int.TryParse(txtQuantity.Value, out quantity) || quantity < 1) { quantity = 1; } // 添加到购物车 Cart cart = GetOrCreateCart(); cart.AddItem(currentProductId, quantity, variant); // 更新购物车数量显示 UpdateCartBadge(cart.TotalItems); // 显示成功消息 ClientScript.RegisterStartupScript(GetType(), "AddToCartSuccess", "showToast('success', '商品已添加到购物车!');", true); } catch (Exception ex) { LogError($"添加到购物车失败: {ex.Message}", ex); ClientScript.RegisterStartupScript(GetType(), "AddToCartError", "showToast('error', '添加到购物车失败,请重试');", true); } } /// <summary> /// 记录页面访问 /// </summary> private void LogPageVisit(int productId) { try { string connString = GetConnectionString(); using (var conn = new SqlConnection(connString)) { string query = @" INSERT INTO ProductVisits (ProductID, UserIP, VisitDate) VALUES (@ProductID, @UserIP, GETDATE())"; using (var cmd = new SqlCommand(query, conn)) { cmd.Parameters.AddWithValue("@ProductID", productId); cmd.Parameters.AddWithValue("@UserIP", GetUserIP()); conn.Open(); cmd.ExecuteNonQuery(); } } } catch { // 访问日志记录失败不影响主流程 } } /// <summary> /// 获取或创建用户购物车 /// </summary> private Cart GetOrCreateCart() { Cart cart = Session["ShoppingCart"] as Cart; if (cart == null) { cart = new Cart(); Session["ShoppingCart"] = cart; } return cart; } /// <summary> /// 更新页面购物车徽章显示 /// </summary> private void UpdateCartBadge(int count) { // 查找母版页中的购物车徽章 var cartBadge = Master?.FindControl("cartBadge") as System.Web.UI.HtmlControls.HtmlGenericControl; if (cartBadge != null) { cartBadge.InnerText = count.ToString(); cartBadge.Visible = count > 0; } } /// <summary> /// 获取数据库连接字符串 /// </summary> private string GetConnectionString() { return WebConfigurationManager.ConnectionStrings["DB-NetShopsConnectionString"]?.ConnectionString; } /// <summary> /// 获取用户IP地址 /// </summary> private string GetUserIP() { string ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (string.IsNullOrEmpty(ip)) { ip = Request.ServerVariables["REMOTE_ADDR"]; } else { string[] addresses = ip.Split(','); if (addresses.Length != 0) { return addresses[0]; } } return ip; } /// <summary> /// 显示错误消息 /// </summary> private void ShowErrorMessage(string message) { if (ltErrorMessage != null) { ltErrorMessage.Text = $"<div class='alert alert-danger'>{HttpUtility.HtmlEncode(message)}</div>"; ltErrorMessage.Visible = true; productContainer.Visible = false; } } /// <summary> /// 记录错误日志 /// </summary> private void LogError(string message, Exception ex) { // 实际项目中应使用日志框架(如log4net/NLog) System.Diagnostics.Debug.WriteLine($"{message}\n{ex}"); // 也可以保存到数据库或文件 try { string logMessage = $"[{DateTime.Now}] {message}\nException: {ex}\n\n"; System.IO.File.AppendAllText(Server.MapPath("~/App_Data/error.log"), logMessage); } catch { // 文件记录失败时不中断 } } } /// <summary> /// 购物车项 /// </summary> public class CartItem { public int ProductId { get; set; } public int Quantity { get; set; } public string Variant { get; set; } public DateTime AddedTime { get; set; } = DateTime.Now; } /// <summary> /// 购物车类 /// </summary> public class Cart { public List<CartItem> Items { get; } = new List<CartItem>(); public int TotalItems => Items.Sum(item => item.Quantity); public decimal TotalPrice { get { // 实际项目中应从数据库获取当前价格 return 0; // 简化为0 } } /// <summary> /// 添加商品到购物车 /// </summary> public void AddItem(int productId, int quantity, string variant = "") { var existingItem = Items.FirstOrDefault(i => i.ProductId == productId && i.Variant == variant); if (existingItem != null) { existingItem.Quantity += quantity; } else { Items.Add(new CartItem { ProductId = productId, Quantity = quantity, Variant = variant }); } } /// <summary> /// 从购物车移除商品 /// </summary> public void RemoveItem(int productId, string variant = "") { var itemToRemove = Items.FirstOrDefault(i => i.ProductId == productId && i.Variant == variant); if (itemToRemove != null) { Items.Remove(itemToRemove); } } /// <summary> /// 清空购物车 /// </summary> public void Clear() { Items.Clear(); } } } 根据后端代码更新数据库代码,使网页能够正常运行
06-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值