22

WebAPI アプリケーションにバージョン管理フレームワークを実装しましたが、Microsoft の新しいヘルプ ページ拡張機能と連動させたいと考えています。

Microsoft.AspNet.WebApi.HelpPage

SDammann.WebApi.バージョン管理

簡単に言えば、両方を連携させる方法がわかりません。私は2つのプロジェクトを持っています:

  • AdventureWorks.Api (メイン ホスト/ルート アプリケーション)
  • AdventureWorks.Api.v1 (API の最初のバージョンを含むクラス ライブラリ)

バージョン管理は期待どおりに機能します。

ルート アプリケーションに HelpPage パッケージをインストールしようとしましたが、ヘルプ ページを参照すると、コントローラーが見つからないように見えます。内部的には、次を使用していると思います:

Configuration.Services.GetApiExplorer().ApiDescriptions

これは結果を返さないため、エラーが発生します。

これらのパッケージの両方を連携させるのを手伝ってくれる人はいますか?

編集: 最初は、これがルーティングの問題であるかどうか確信が持てませんでしたが、最近のコメントは別のことを示唆しているようです。ここに私のRouteConfig.csがあります

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapHttpRoute(
            name: "SldExportAliasApi",
            routeTemplate: "api/v{version}/sld-export/{id}",
            defaults: new { id = RouteParameter.Optional, controller = "Export" }
        );

        routes.MapHttpRoute(
            name: "LinkRoute",
            routeTemplate: "api/v{version}/link/{system}/{deployment}/{view}",
            defaults: new { controller = "Link" }
        );

        routes.MapHttpRoute(
             name: "DefaultSubParameterApi",
             routeTemplate: "api/v{version}/{controller}/{id}/{param}",
             defaults: new { id = RouteParameter.Optional, param = RouteParameter.Optional }
        );

        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/v{version}/{controller}/{action}/{id}",
            defaults: new { action = "Index", id = RouteParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
4

3 に答える 3

11

プロジェクトの AdventureWorks.Api.v1 プロジェクトからドキュメント XML ファイルを取得し、それを AdventureWorks.Api プロジェクトの bin フォルダーに配置する必要があります。

次に、次の行を Application_Start メソッドに追加します。

// enable API versioning
        GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new RouteVersionControllerSelector(GlobalConfiguration.Configuration));
        GlobalConfiguration.Configuration.Services.Replace(typeof(IApiExplorer), new VersionedApiExplorer(GlobalConfiguration.Configuration));
        GlobalConfiguration.Configuration.Services.Replace(typeof(IDocumentationProvider),
                                new XmlCommentDocumentationProvider(System.IO.Path.GetDirectoryName(
                                    System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) +
                                                                    "\\Adventure.Api.v1.XML"));

次に、ドキュメントで API を表示できます。

バージョン番号が正しく取得されず、??? に置き換えられることがあります。

これを修正するには、次を追加します。

if (api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace != null)
    {
        var versionName = api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace.Replace(".Controllers", "").Split('.').Last();
        api.RelativePath = api.RelativePath.Replace("v???", versionName);
    }

この場所で正確にあなたの ApiGroup.cshtml に:

@foreach (var api in Model)
{
    if (api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace != null)
    {
        var versionName = api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace.Replace(".Controllers", "").Split('.').Last();
        api.RelativePath = api.RelativePath.Replace("v???", versionName);
    }
    <tr>
        <td class="api-name"><a href="@Url.Action("Api", "Help", new { apiId = api.GetFriendlyId() })">@api.HttpMethod.Method @api.RelativePath</a></td>
        <td class="api-documentation">
        @if (api.Documentation != null)
        {
            <p>@api.Documentation</p>
        }
        else
        {
            <p>No documentation available.</p>
        }
        </td>
    </tr>
}

これでうまくいくはずです!

于 2013-05-03T09:08:40.953 に答える
4

投稿にコメントする方法がわかりませんでした:(これはおそらく、この質問に対するマークされた回答の下のコメントであるはずですが、SDammanは更新されており、私がする必要があったのはこれだけでした

// enable API versioning                   
GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerSelector), 
     new SDammann.WebApi.Versioning.RouteVersionedControllerSelector(GlobalConfiguration.Configuration));

GlobalConfiguration.Configuration.Services.Replace(typeof(IApiExplorer), new SDammann.WebApi.Versioning.VersionedApiExplorer(GlobalConfiguration.Configuration));

VersionedApiExplorer というタイプがあり、うまく機能します。これにより、ソリューションがはるかに簡単になることを願っています。

編集:自分でもう一度作業を手伝おうとした後、自分の答えがまったく明白ではないことに気付きました。

ヘルプ ページを機能させるために必要な唯一のことは、グローバル構成の IApiExplorer を置き換えることだけです。sdammans の指示に従ってハンドラーを変更した直後に実行してください。

于 2013-05-22T20:13:43.857 に答える
1

@mortwareに同意します。デフォルトのウェブAPIのルーティングでは、デフォルトのGet()/Post()メソッドを使用している場合、URLは「site / api /controllerName/」のようになります。特定の名前のメソッドを使用している場合、ルートは「site / api / controllerName/methodName」のようになります。

また、パラメータ名に問題が発生しました。たとえば、/ App_Start/WebApiConfig.csで指定されたルートにある場合。

// Controller with ID
// To handle routes like `/api/VTRouting/1`
config.Routes.MapHttpRoute(
    name: "ControllerAndId",
    routeTemplate: "api/{controller}/{id}",
    defaults: null,
    constraints: new { id = @"^\d+$" } // Only integers 
);

// Controllers with Actions
// To handle routes like `/api/VTRouting/route`
config.Routes.MapHttpRoute(
    name: "ControllerAndAction",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: null,
    constraints: new { id = @"^\d+$" } // Only integers 
);

次に、http動詞のメソッドパラメータには、「id」というパラメータが必要です。

// url: site/api/controller/<int>
public HttpResponseMessage Get(int id) { return null; /*dummy*/ }

// url: site/api/controller/<int>
public HttpResponseMessage Post(int id) { return null; /*dummy*/ }

// url: site/api/controller/SomeAction/<int>
public HttpResponseMessage SomeAction(int id) { return null; /*dummy*/ }

あなたが次のようなものを持っている場合;

public HttpResponseMessage Get(int myID) { return null; /*dummy*/ }

「myID」パラメータがルートで指定されたものと一致しないため、機能しませ{id}。@OakNinjaが指摘したように、正確な原因を特定するために、WebApiConfig.csでのルーティングが必要になります。

于 2013-02-18T18:01:00.117 に答える