いくつかのコントローラーを持つ ASP.NET Web API (.NET 4) アプリケーションがあります。IIS で Web API アプリケーションの複数のインスタンスを実行しますが、1 つの違いがあります。特定の IIS インスタンスでは、特定のコントローラーのみを使用できます。私が考えていたのは、インスタンスの起動時にインスタンスに適用されないコントローラーを無効化/アンロードすることです。
これについて正しい方向に私を導くことができる情報を誰かが手に入れましたか?
いくつかのコントローラーを持つ ASP.NET Web API (.NET 4) アプリケーションがあります。IIS で Web API アプリケーションの複数のインスタンスを実行しますが、1 つの違いがあります。特定の IIS インスタンスでは、特定のコントローラーのみを使用できます。私が考えていたのは、インスタンスの起動時にインスタンスに適用されないコントローラーを無効化/アンロードすることです。
これについて正しい方向に私を導くことができる情報を誰かが手に入れましたか?
IHttpControllerActivator
DefaultHttpControllerActivator を装飾することで、独自のカスタムを組み込むことができます。内部では、設定を確認し、許可されている場合にのみコントローラーを作成します。
Create メソッドから null を返すと、ユーザーは 404 Not Found メッセージを受け取ります。
私の例では、アプリ設定 (App.Config または Web.Config) の値がチェックされていることを示していますが、明らかにこれは他の環境認識条件である可能性があります。
public class YourCustomControllerActivator : IHttpControllerActivator
{
private readonly IHttpControllerActivator _default = new DefaultHttpControllerActivator();
public YourCustomControllerActivator()
{
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
if (ConfigurationManager.AppSettings["MySetting"] == "Off")
{
//Or get clever and look for attributes on the controller in controllerDescriptor.GetCustomAttributes<>();
//Or use the contoller name controllerDescriptor.ControllerName
//This example uses the type
if (controllerType == typeof (MyController) ||
controllerType == typeof (EtcController))
{
return null;
}
}
return _default.Create(request, controllerDescriptor, controllerType);
}
}
次のようにアクティベーターを切り替えることができます。
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new YourCustomControllerActivator());
アップデート
この質問を見てからしばらく経ちましたが、今日それに取り組むとしたら、アプローチを少し変更してカスタムを使用しますIHttpControllerSelector
。これはアクティベーターの前に呼び出され、コントローラーを有効および無効にするためのわずかに効率的な場所になります... (ただし、他のアプローチは機能します)。から装飾または継承できるはずですDefaultHttpControllerSelector
。
コントローラーをアンロードするのではなく、許可を付与するかどうかを決定する際にインスタンス情報を参照するカスタムの Authorize 属性を作成すると思います。
クラス レベルで各コントローラーに以下を追加するか、個々のコントローラー アクションに追加することもできます。
[ControllerAuthorize (AuthorizedUserSources = new[] { "IISInstance1","IISInstance2","..." })]
属性のコードは次のとおりです。
public class ControllerAuthorize : AuthorizeAttribute
{
public ControllerAuthorize()
{
UnauthorizedAccessMessage = "You do not have the required access to view this content.";
}
//Property to allow array instead of single string.
private string[] _authorizedSources;
public string UnauthorizedAccessMessage { get; set; }
public string[] AuthorizedSources
{
get { return _authorizedSources ?? new string[0]; }
set { _authorizedSources = value; }
}
// return true if the IIS instance ID matches any of the AllowedSources.
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
throw new ArgumentNullException("httpContext");
//If no sources are supplied then return true, assuming none means any.
if (!AuthorizedSources.Any())
return true;
return AuthorizedSources.Any(ut => ut == httpContext.ApplicationInstance.Request.ServerVariables["INSTANCE_ID"]);
}
コントローラーのIHttpControllerActivator
オン/オフを切り替え、デフォルトですべてのルート コントローラーをキャッチする必要がある場合、実装は属性 routing を使用して定義されたルートを無効にしません。を使用してスイッチをオフIHttpControllerActivator
にすると、コントローラーが無効になりますが、ルートが要求されたときに、キャッチオールルートコントローラーにヒットしません。削除されたコントローラーにヒットしようとするだけで、コントローラーが登録されていません。