, - API 2 ( ) (.. , "api-version" querystring "api- = XXX".
HTTP- :
public class RouteVersionHttpConstraint : IHttpRouteConstraint
{
public const string VersionHeaderName = "api-version";
private const int DefaultVersion = 1;
public RouteVersionHttpConstraint(int allowedVersion)
{
AllowedVersion = allowedVersion;
}
public int AllowedVersion
{
get;
private set;
}
public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
if (routeDirection == HttpRouteDirection.UriResolution)
{
int version = GetVersionHeaderOrQuery(request) ?? DefaultVersion;
if (version == AllowedVersion)
{
return true;
}
}
return false;
}
private int? GetVersionHeaderOrQuery(HttpRequestMessage request)
{
string versionAsString;
IEnumerable<string> headerValues;
if (request.Headers.TryGetValues(VersionHeaderName, out headerValues) && headerValues.Count() == 1)
{
versionAsString = headerValues.First();
int version;
if (versionAsString != null && Int32.TryParse(versionAsString, out version))
{
return version;
}
}
else
{
var query = System.Web.HttpUtility.ParseQueryString(request.RequestUri.Query);
string versionStr = query[VersionHeaderName];
int version = 0;
int.TryParse(versionStr, out version);
if (version > 0)
return version;
}
return null;
}
}
factory:
public class RouteVersionAttribute : RouteFactoryAttribute
{
public int Version { get; private set; }
public RouteVersionAttribute() : this(null, 1)
{
}
public RouteVersionAttribute(int version) : this(null, version)
{
}
public RouteVersionAttribute(string template, int version)
: base(template)
{
Version = version;
}
public override IDictionary<string, object> Constraints
{
get
{
var constraints = new HttpRouteValueDictionary();
constraints.Add("version", new RouteVersionHttpConstraint(Version));
return constraints;
}
}
public override IDictionary<string, object> Defaults
{
get
{
var defaults = new HttpRouteValueDictionary();
defaults.Add("version", 1);
return defaults;
}
}
}
:
[RouteVersion("api/versiontest", 1)]
public class Version1TestController : BaseApiController
{
[HttpGet]
public HttpResponseMessage get()
{
return Request.CreateResponse(HttpStatusCode.OK, new { Version = "API Version 1 selected" });
}
}
[RouteVersion("api/versiontest", 2)]
public class Version2TestController : ApiController
{
[HttpGet]
public HttpResponseMessage get()
{
return Request.CreateResponse(HttpStatusCode.OK, new { Version = "API Version 2 selected" });
}
}