ASP.NET Web表单间传值遇System.NullReferenceException及更新失效问题
解决ASP.NET页面传值与NullReferenceException及SQL更新无效问题
首先得说清楚你遇到的几个核心问题的根源,再一步步给你解决方案:
1. 为什么实例化页面对象传值会抛NullReferenceException?
ASP.NET Web Forms的页面是由服务器严格管理生命周期的——你在第一个页面Button2_Click里new editar(...)创建的对象,和Response.Redirect后服务器为渲染editar.aspx新建的页面实例完全不是同一个。更关键的是,页面构造函数执行时,控件(比如tname文本框)还没完成初始化(控件要到Init阶段才会被创建),这时候直接给tname.Text赋值,自然会因为tname是null抛出异常。
2. 为什么POST/Session传值后刷新会重复加载、SQL执行但数据库没变化?
大概率是你没判断IsPostBack,导致页面每次回发(比如点击更新按钮)都重新从Session/POST里取值覆盖文本框;另外你用字符串拼接SQL的写法,不仅有严重的SQL注入风险,还可能因为特殊字符(比如单引号)导致SQL语法错误,看起来执行了但实际没生效。
正确的页面传值方案
这里给你两种常用且靠谱的方式:
方案一:使用QueryString(适合非敏感的简单字符串)
第一个页面的按钮点击事件:
protected void Button2_Click(object sender, EventArgs e) { // 对特殊字符做URL编码,避免传值出错 string encodedName = Server.UrlEncode(tname.Text.Trim()); Response.Redirect($"editar.aspx?name={encodedName}"); }
第二个页面editar.aspx的Page_Load事件:
protected void Page_Load(object sender, EventArgs e) { // 只在首次加载页面时赋值,回发时不重复操作 if (!IsPostBack) { if (Request.QueryString["name"] != null) { string name = Server.UrlDecode(Request.QueryString["name"]); tname.Text = name; } } }
方案二:使用Session(适合敏感数据或复杂数据)
第一个页面的按钮点击事件:
protected void Button2_Click(object sender, EventArgs e) { Session["TargetUserName"] = tname.Text.Trim(); Response.Redirect("editar.aspx"); }
第二个页面editar.aspx的Page_Load事件:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { if (Session["TargetUserName"] != null) { tname.Text = Session["TargetUserName"].ToString(); // 用完及时清除Session,避免后续误触发 Session.Remove("TargetUserName"); } } }
修复SQL更新无效的问题
绝对不要用字符串拼接SQL,换成参数化查询,既避免注入风险,也能解决特殊字符导致的语法错误:
protected void Button2_Click(object sender, EventArgs e) { // 使用using自动管理连接和命令的生命周期,避免资源泄漏 using (NpgsqlConnection conn = new NpgsqlConnection("你的数据库连接字符串")) { conn.Open(); string updateSql = "UPDATE usuario SET cedula = @cedula WHERE nombre = @nombre"; using (NpgsqlCommand upt = new NpgsqlCommand(updateSql, conn)) { // 添加参数,确保数据正确传递 upt.Parameters.AddWithValue("@cedula", tcedula.Text.Trim()); upt.Parameters.AddWithValue("@nombre", tname.Text.Trim()); // 执行并获取受影响行数,方便排查问题 int affectedRows = upt.ExecuteNonQuery(); if (affectedRows == 0) { // 说明没有匹配到对应的nombre记录,检查数据是否完全匹配(Postgres默认区分大小写) Response.Write("未找到要更新的用户记录,请检查用户名是否正确"); } else { Response.Write($"成功更新 {affectedRows} 条记录"); } } } }
另外还要注意:Postgres默认是区分大小写的,如果数据库里的nombre字段值是"Daniel",你传"daniel"是匹配不到的,这点也要确认。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

