title: Where to validate input parameters to prevent SQL injection in C# web API controller or service or repository?
body: <p><strong>I understand that parameterized queries is sufficient for preventing SQL injection. Is it good practice to validate the input parameters as well? What's a good way to validate the input parameters and where (controller, service, repository) do I validate them?</strong></p>
  <p>This is my controller method:</p>
  <pre><code>public async Task&lt;ActionResult&lt;List&lt;Level&gt;&gt;&gt; GetLevelsAsync([FromRoute] string Code, string Year)
  {
      int appId = IsoCode.FromName(Code).Id;
      var result = await _sampleService.GetLevelsAsync(appId, Year);
      return result;
  }
  </code></pre>
  <p>This is my service method:</p>
  <pre><code>public async Task&lt;List&lt;Level&gt;&gt; GetLevelsAsync(int appId, string year)
  {
      if (string.IsNullOrWhiteSpace(year) == true)
          throw new ArgumentNullException(nameof(year));
  
      var result = await _sampleRepository.GetLevelsByYear(appId, year);
      return result;
  }
  </code></pre>
  <p>This is my repository method:</p>
  <pre><code>public async Task&lt;List&lt;Level&gt;&gt; GetLevelsByYear(int appId, string year)
  {
      if (string.IsNullOrWhiteSpace(year))
          throw new ArgumentNullException(nameof(year));
  
      var result = new List&lt;Level&gt;();
      var parameters = new { AppId = appId, Year = year };
      string sql = @&quot;
                  SELECT * 
                  FROM [Levels] as l, [LevelYears] as v 
                  WHERE 
                      v.LevelId = l.Id AND l.Active = 1 AND l.AppId = @AppId AND v.Year = @Year
                  ORDER BY v.Sort asc
          &quot;;
  
      using (IDbConnection db = new SqlConnection(_settings.SqlServerConnString))
      {
          try
          {
              result = db.Query&lt;Level&gt;(sql, parameters).ToList();
          }
          catch (Exception e)
          {
              _logger.LogError(e, &quot;Error querying levels by year&quot;, new { appId, year });
              throw;
          }
      }
      return result;
  }
  </code></pre>