私のプロジェクトでは、カスタムルーティング変数を実装して、カスタムヘッダー変数(APIバージョン)を使用してthis sample project on Codeplexに似ていましたが、メジャー。マイナーコンベンションのために。Web APIのヘルプページを取得してカスタムルーティング制約を使用する
これは、その経路FullVersionedRoute属性によって区別される2つの別々のコントローラ作成含む:
Sample1Controller.cs
/// <summary>
/// v1.0 Controller
/// </summary>
public class Sample1Controller : ApiController
{
[FullVersionedRoute("api/test", "1.0")]
public IEnumerable<string> Get()
{
return new[] { "This is version 1.0 test!" };
}
}
Sample2Controller.cs
/// <summary>
/// v2.0 Controller
/// </summary>
public class Sample2Controller : ApiController
{
[FullVersionedRoute("api/test", "2.0")]
public IEnumerable<string> Get()
{
return new[] { "This is version 2.0 test!" };
}
}
FullVersionedRoutをe.cs
using System.Collections.Generic;
using System.Web.Http.Routing;
namespace HelperClasses.Versioning
{
/// <summary>
/// Provides an attribute route that's restricted to a specific version of the api.
/// </summary>
internal class FullVersionedRoute : RouteFactoryAttribute
{
public FullVersionedRoute(string template, string allowedVersion) : base(template)
{
AllowedVersion = allowedVersion;
}
public string AllowedVersion
{
get;
private set;
}
public override IDictionary<string, object> Constraints
{
get
{
var constraints = new HttpRouteValueDictionary();
constraints.Add("version", new FullVersionConstraint(AllowedVersion));
return constraints;
}
}
}
}
FullVersionConstraint.cs
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http.Routing;
namespace HelperClasses.Versioning
{
/// <summary>
/// A Constraint implementation that matches an HTTP header against an expected version value.
/// </summary>
internal class FullVersionConstraint : IHttpRouteConstraint
{
public const string VersionHeaderName = "api-version";
private const string DefaultVersion = "1.0";
public FullVersionConstraint(string allowedVersion)
{
AllowedVersion = allowedVersion;
}
public string AllowedVersion
{
get;
private set;
}
public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
if (routeDirection == HttpRouteDirection.UriResolution)
{
var version = GetVersionHeader(request) ?? DefaultVersion;
return (version == AllowedVersion);
}
return false;
}
private string GetVersionHeader(HttpRequestMessage request)
{
IEnumerable<string> headerValues;
if (request.Headers.TryGetValues(VersionHeaderName, out headerValues))
{
// enumerate the list once
IEnumerable<string> headers = headerValues.ToList();
// if we find once instance of the target header variable, return it
if (headers.Count() == 1)
{
return headers.First();
}
}
return null;
}
}
}
これはうまく動作しますが、彼らは同じルート(ように見えるようauto-generated help filesは二つのコントローラのアクションを区別することはできませんあなたがURLルートに注意を払うのであれば、それはデフォルトで行われます)。そのため、Sample2Controller.csのアクションはSample1Controller.csのアクションを上書きし、Sample2 APIのみがヘルプページに表示されます。
Web APIヘルプページパッケージを構成してカスタム制約を認識し、2つの別々のAPIが存在することを認識し、その後ヘルプページに別々のAPIグループとして表示する方法はありますか?
カスタムルートを使用するだけで同様の問題が発生します。私の質問は、サーバー/ approot /バージョンに展開しない理由は、同じコードベースにネストされた複数のバージョンをすべてのバージョンに変更することは、ロジックが変更されてはいけない元のバージョンを100%にすることはできません – workabyte
この記事によれば、そのソリューションは複数の異なるリソース(つまりv1/myresource、v2/myresource、v3/myresource)を持っているという印象を与えるからです。実際には1つのリソース(すなわち/ myresource)が存在し、その異なるバージョン(Acceptヘッダーに基づいて提供されます。これはHTTP SPECの目的です)。これは意味論的な議論です。 http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html – bperniciaro