You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
}

错误原因

  1. SQL语法错误:字符串类型的answer直接拼接进SQL语句,未加单引号。如果answer的值是On这类SQL关键字,会导致SQL语句变成WHERE answer = On,触发语法错误。
  2. 核心逻辑混乱:
    • 错误地把ExecuteScalar的返回值赋值给CommandText,完全覆盖了原本的查询语句,后续对比逻辑完全无效。
    • 传入的gameId和trackId参数未被使用,不符合验证玩家答案的业务逻辑。
    • 验证逻辑错误:拿Track表的Title和Song表查询结果的第一列(gameId)做对比,完全不匹配业务需求。
  3. SQL注入风险:直接拼接字符串生成SQL,存在严重的安全漏洞。
  4. 资源管理不当:未使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:15:25