C# API游戏答案验证报错:SqlException(On关键字附近语法错误)
C# API验证玩家答案时SqlException错误解决
问题场景
开发C# API用于验证游戏玩家输入的答案是否正确(数据来自数据库),编写了数据库类的VerifQuestions方法及API控制器后,运行时抛出System.Data.SqlClient.SqlException错误,提示Incorrect syntax near the keyword 'On'。
现有代码如下:
数据库类代码
public string VerifQuestions(int gameId, int trackId, int answerTypeId, string answer) { string result = ""; _sqlConnection.Open(); //It opens my connection to my DB SqlCommand cmd = _sqlConnection.CreateCommand(); SqlCommand cmd1 = _sqlConnection.CreateCommand(); //create my command = cmd.CommandText = "SELECT gameId, trackId, answerTypeId, answer FROM Song WHERE answer =" + answer; //request sql cmd1.CommandText = "SELECT Title FROM Track WHERE id =" + answerTypeId; //SqlDataReader reader = cmd.ExecuteReader(); cmd.CommandText = (string)cmd.ExecuteScalar(); cmd1.CommandText = (string)cmd1.ExecuteScalar(); //executeScalar is a function to execute our query //and returns the first column of the first row if (cmd1.CommandText == cmd.CommandText) { result = "true"; } else { result = "false"; } _sqlConnection.Close(); return result; }
API控制器代码
//This request will tell if the question entered is the correct answer //the user will have to enter the gameId, the trackId, the answer id, and the answer of the question // GET api/<ArticleArtistController>/5 [HttpGet("gameId")] public string VerifQuestions(int gameId, int trackId, int answerTypeId, string answer) { return _db.VerifQuestions(gameId, trackId, answerTypeId, answer); }
错误原因
- SQL语法错误:字符串类型的
answer直接拼接进SQL语句,未加单引号。如果answer的值是On这类SQL关键字,会导致SQL语句变成WHERE answer = On,触发语法错误。 - 核心逻辑混乱:
- 错误地把
ExecuteScalar的返回值赋值给CommandText,完全覆盖了原本的查询语句,后续对比逻辑完全无效。 - 传入的
gameId和trackId参数未被使用,不符合验证玩家答案的业务逻辑。 - 验证逻辑错误:拿
Track表的Title和Song表查询结果的第一列(gameId)做对比,完全不匹配业务需求。
- 错误地把
- SQL注入风险:直接拼接字符串生成SQL,存在严重的安全漏洞。
- 资源管理不当:未使用
using语句确保数据库连接、命令等资源自动释放,可能引发连接泄漏。
修复方案
1. 修正数据库类代码
public bool VerifQuestions(int gameId, int trackId, int answerTypeId, string answer) { // using语句自动管理连接生命周期,确保连接关闭和释放 using (_sqlConnection) { _sqlConnection.Open(); // 参数化查询,避免语法错误和SQL注入 string sql = @"SELECT COUNT(*) FROM Song WHERE gameId = @GameId AND trackId = @TrackId AND answerTypeId = @AnswerTypeId AND answer = @Answer"; using (SqlCommand cmd = new SqlCommand(sql, _sqlConnection)) { // 添加参数绑定 cmd.Parameters.AddWithValue("@GameId", gameId); cmd.Parameters.AddWithValue("@TrackId", trackId); cmd.Parameters.AddWithValue("@AnswerTypeId", answerTypeId); cmd.Parameters.AddWithValue("@Answer", answer); // 执行查询,返回匹配记录数 int matchCount = (int)cmd.ExecuteScalar(); // 有匹配则答案正确 return matchCount > 0; } } }
2. 修正API控制器代码
/// <summary> /// 验证玩家输入的答案是否正确 /// </summary> /// <param name="gameId">游戏ID</param> /// <param name="trackId">曲目ID</param> /// <param name="answerTypeId">答案类型ID</param> /// <param name="answer">玩家输入的答案</param> /// <returns>验证结果</returns> [HttpGet("verify-answer")] public IActionResult VerifQuestions(int gameId, int trackId, int answerTypeId, string answer) { bool isCorrect = _db.VerifQuestions(gameId, trackId, answerTypeId, answer); return Ok(new { IsCorrect = isCorrect }); }
修复说明
- 将返回类型从
string改为bool,符合C#类型规范,避免字符串硬编码的冗余。 - 采用参数化查询,彻底解决SQL注入风险和字符串拼接导致的语法错误。
- 使用
using语句自动释放数据库资源,避免连接泄漏问题。 - 修正API路由为语义化的
verify-answer,返回结构化JSON数据,符合RESTful API设计规范。 - 正确使用所有传入参数,验证逻辑匹配业务需求:检查是否存在同时匹配
gameId、trackId、answerTypeId且answer正确的记录。
内容的提问来源于stack exchange,提问作者Eloi Jahan
相关产品推荐
相关产品推荐

