无法为where子句转换guid

时间:2019-07-05 09:53:00

标签: c#

我在这里遇到一个真正的问题,该函数会将指南传递给该函数,该函数在其他地方都可以使用,我不明白我在做什么错。

public bool DoesBomExistForHandeldId(string HandHeldId, string reference)
{
  List<BomComponentData> result = new List<BomComponentData>();
   try
    {
      using (var connection = new SqlConnection(ConfigurationManager.AppSettings["DataConnectionLive"]))
      {
         connection.Open();
         string sql = "select * from Fuel_BomTransAction where deviceId='" + HandHeldId  + "' and Reference = '" + reference + "'";
         logger.Info("SQL For the exist transactions");
         result = connection.Query<BomComponentData>(sql).ToList();

        }
        }
      catch (Exception ex)
      {
            logger.Warn("Error occoured on  DoesBomExistForHandeldId funciton " + ex.Message.ToString());
      }
      if (result.Count > 0)
          return true;
      else
          return false;
}

我在日志中返回的错误如下

  

2019-07-05 10:47:26.3561 .lambda_method =>   BomTransferController.DoesBomExistForHandeldId =>   StockManager.DoesBomExistForHandeldId发生错误   转换时,DomsBomExistForHandeldId函数是否转换失败   从字符串到uniqueidentifier。

我已经进行了搜索,并且尝试了相同的转换方法结果,该列是唯一标识符,并且它是通过的有效Guid。

1 个答案:

答案 0 :(得分:-1)

问题是使用字符串串联来创建SQL查询,而不是强制转换。这可能导致SQL注入攻击和转换问题,就像您遇到的那样。 HandHeldId作为字符串传递,这意味着不能保证它包含实际的GUID。它可能包含数字或类似'; truncate table Fuel_BomTransAction;--之类的恶意内容。

Query<>不是ADO.NET方法。我怀疑您正在使用Dapper,这使得使用适当的参数化查询变得微不足道。

方法应如下所示:

public bool DoesBomExistForHandeldId(Guid HandHeldId, string reference)
{
    string sql = @"select * from Fuel_BomTransAction 
                   where deviceId=@deviceId and Reference = @reference";

    try
    {
      using (var connection = new SqlConnection(ConfigurationManager.AppSettings["DataConnectionLive"]))
      {
         connection.Open();
         logger.Info("SQL For the exist transactions");
         var result = connection.Query<BomComponentData>(sql,
                            new { 
                                  deviceId=HandHeldId,
                                  reference=reference});
         return result.Any();
      }
   }
   catch (Exception ex)
   {
        logger.Warn("Error occoured on  DoesBomExistForHandeldId funciton " + ex.Message);
        return false;
   }
}

HandHeldId的类型现在为Guid。这些值作为名为@deviceId@reference的参数发送到服务器。

此查询仍然过于昂贵。当我们仅对是否存在匹配项感兴趣时,没有理由加载整个Fuel_BomTransAction行。查询可以更改为

string sql = @"select TOP 1 1 from Fuel_BomTransAction 
               where deviceId=@deviceId and Reference = @reference";

如果找到匹配项,则只会返回一个1