ASP.NET MVC Details视图使用string类型id参数的代码错误排查
ASP.NET MVC Details接口查询异常错误排查
以下是代码中存在的明确问题,按影响优先级排序:
- SQL语法错误+注入风险:
CardCode是数据库中的字符串类型字段,直接拼接id参数时没有给字符串值加单引号,生成的SQL语句会把传入的id值识别为列名,直接抛出语法错误;同时字符串拼接SQL的写法存在严重SQL注入漏洞,恶意传入特殊参数可以拖库、删表。 - 参数校验逻辑顺序颠倒+无效判断:代码先打开数据库连接,才判断
id是否为空,且判断块内没有写任何拦截、返回逻辑,属于完全无效的代码;空id场景下会直接执行无效SQL抛错,还会白白占用数据库连接资源。 - 非托管资源未完全释放:
SqlCommand、SqlDataReader都属于需要手动释放的非托管资源,现有代码只包裹了SqlConnection的释放逻辑,长期运行会出现内存泄漏、连接池占满的问题。 - 空结果场景未处理:如果传入的id查不到对应业务数据,
SqlDataReader不会进入读取循环,返回给视图的BPModel实例属性全为空,视图渲染时会抛出空引用异常。
修正后可运行代码
public ActionResult Details(string id) { // 第一步先做参数校验,无效参数直接返回,不进入数据库逻辑 if (string.IsNullOrEmpty(id)) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "参数id不能为空"); } BPModel BP = new BPModel(); string connectionString = ConfigurationManager.ConnectionStrings["SAPB1"].ConnectionString; // 所有非托管资源都用using包裹,出作用域自动释放 using (SqlConnection conn = new SqlConnection(connectionString)) { // 用参数化查询,完全避免SQL注入和字符串拼接语法问题 string sql = "Select a.[CardCode] As CCODE,a.[CardName] As Name from ocrd a where a.CardCode = @CardCode"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { // 给SQL参数赋值 cmd.Parameters.AddWithValue("@CardCode", id); conn.Open(); using (SqlDataReader rdr = cmd.ExecuteReader()) { if (!rdr.HasRows) { // 查不到对应数据直接返回404,不要传空模型给视图触发空引用异常 return HttpNotFound(); } while (rdr.Read()) { BP.CCODE = rdr["CCODE"].ToString(); BP.Name = rdr["Name"].ToString(); } } } } return View(BP); }
如果项目已经引入EF、Dapper这类ORM框架,直接用ORM做数据查询可以省去大量手动处理连接、资源释放、参数绑定的重复代码,出错概率会低很多。
内容的提问来源于stack exchange,提问作者Rex Regalado
相关产品推荐
相关产品推荐

