Web API コントローラーを動的に登録および登録解除して、新しい属性ルーティング メカニズムを使用できるカスタム ソリューションをアップグレードしています。ただし、RTM への最近の更新により、私のソリューションが壊れているようです。
私のソリューションでは、管理目的でいくつかの Web Api コントローラーを公開しています。これらは、新しい HttpConfigurationExtensions.MapHttpAttributeRoutes メソッド呼び出しを使用して登録されます。
このソリューションでは、Web Api コントローラーをサード パーティのアセンブリでホストし、動的に登録することもできます。この段階で、サードパーティのコントローラーが読み込まれた後に HttpConfigurationExtensions.MapHttAttributeRoutes をもう一度呼び出すと、例外が発生します。したがって、私のソリューションではリフレクションを使用して RoutePrefix 属性と Route 属性を調べ、対応するルートを HttpConfiguration オブジェクトに登録します。
残念ながら、Web API を呼び出すと、次のエラーが発生します。
「リクエストURIに一致するHTTPリソースが見つかりませんでした」.
これが私が使いたい単純なコントローラーです:
[RoutePrefix("api/ze")]
public sealed class ZeController : ApiController
{
[HttpGet]
[Route("one")]
public string GetOne()
{
return "One";
}
[HttpGet]
[Route("two")]
public string GetTwo()
{
return "Two";
}
[HttpPost]
[Route("one")]
public string SetOne(string value)
{
return String.Empty;
}
}
これが私が試した最初の解決策です:
configuration.Routes.MapHttpRoute("ZeApi", "api/ze/{action}");
私が試した2番目の解決策は次のとおりです。
var type = typeof(ZeController);
var routeMembers = type.GetMethods().Where(m => m.IsPublic);
foreach (MethodInfo method in routeMembers)
{
var routeAttribute = method.GetCustomAttributes(false).OfType<RouteAttribute>().FirstOrDefault();
if (routeAttribute != null)
{
string controllerName = type.Name.Substring(0, type.Name.LastIndexOf("Controller"));
string routeTemplate = string.Join("/", "api/Ze", routeAttribute.Template);
configuration.Routes.MapHttpRoute(method.Name, routeTemplate);
}
}
IHttpRoute を実装するカスタム クラスを作成し、それらを構成に登録しようとしても役に立たないという 3 番目の解決策も試しました。
新しいルーティング属性に含まれる情報に基づいて、レガシー スタイルのルート マッピングを使用することは可能ですか?
アップデート
Web Api Route Debuggerを使用してルーティング選択プロセスのトラブルシューティングを行うために、コントローラーを Web アプリケーションにインストールしました。スクリーンショットの結果は次のとおりです。
ご覧のとおり、正しいアクションが選択されているように見えますが、それでも 404 エラーが発生します。
Update2
さらに分析した結果、以下の Kiran Challa のコメントによると、Web Api の設計により、属性ルーティングと従来のルーティングを混在させることができず、私がやりたいことはこのアプローチでは実現できないようです。
Web API の [Route] 属性と同じ目的を果たすカスタム属性 [RouteEx] を作成したところ、コードが完全に機能するようになりました。
これは従来の属性ルーティングを使用しては不可能であるため、この質問に対する回答はどれも正当に有効であると見なすことができなかったと思います。だから私はまだ答えを指名していません。