title: ASP.NET API version ranges
body: <p>Our product is a <code>client/server</code> app that has multiple versions of the client out in the field but has only one server that runs the latest version to service all <code>API</code> calls. We have/will have hundreds of <code>API</code> endpoints and I'm trying how best to handle versioning. What I'd like to do is be able to avoid the laborious task of applying <code>attributes</code> to every single method, or copy entire controllers every time we make a minor change.</p>
  <p>I might be misinterpreting most documents/practices on this, but it seems like every time you bump your <code>API</code> you have to go through and do all that work, which seems inefficient at best.</p>
  <p><strong>Instead what I'd like to do is apply an <code>attribute</code> to each endpoint with the version of <em>when it was written</em>, then the client finds the <em>the closest version that is equal to or less than the client version</em>.</strong></p>
  <p>For instance, if an endpoint was written at <code>[ApiVersion(&quot;1.0&quot;)]</code> then that is the attribute it gets. If we had to modify it, I'd copy the method, rename it, apply a <code>RoutePrefix</code> <code>attribute</code> so it gets properly hit and apply a new <code>attribute</code> with the version of our whole <code>API</code> (in this example I put <code>1.5</code>).</p>
  <p>Here is a simple example:</p>
  <pre><code>[HttpGet]
  [ApiVersion(&quot;1.0&quot;)]
  [Route(&quot;GetHeartBeat&quot;)]
  public bool GetHeartBeat()
  {
      return true;
  }
  
  [HttpGet]
  [ApiVersion(&quot;1.5&quot;)]
  [Route(&quot;GetHeartBeat&quot;)]
  public bool GetHeartBeat2()
  {
      return false;
  }
  </code></pre>
  <p>This works no problem when I use url versioning:</p>
  <ul>
  <li><code>/api/v1.0/GetHeartBeat</code>
  or</li>
  <li><code>/api/v1.5/GetHeartBeat</code></li>
  </ul>
  <p>but <code>/api/v1.3/GetHeartBeat</code> does not since that version doesn't exist..</p>
  <p>What I want to happen is if I have a client that is running <code>1.3</code>, then it will find <em>the closest version that is equal to or less than the latest version</em>. So <code>/api/v1.3/GetHeartBeat</code> would get received, since <code>1.3</code> doesn't exist, then it'll look at the closest/earlier version, in this case would be <code>1.0</code>.</p>
  <p>I can write a bunch of route logic to accomplish this, but I feel like there has to be a solution out of the box as I can't be the first person to try this. Is there a <code>nuget</code> package that would accomplish this?</p>