首页 > 解决方案 > 为 where 子句投射指南时遇到问题

问题描述

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

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 从字符串转换为唯一标识符时,DoesBomExistForHandeldId 函数发生错误转换失败。

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

标签: c#

解决方案


问题是使用字符串连接来创建 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如果找到匹配项,这只会返回一个


推荐阅读