私はかなり遅く、これを答える明らかだけど、私はMVC5で特定のアクションのためにIValueProvider
を変更する方法を開発しました。私はMVC3でこれが可能かどうか見ていく努力を怠っていません。なぜならこの質問は古かったからですが、やや似ていると思います。
免責事項:それはかなりではありません。
まず、我々は、アクション固有の設定を行うために属性に実装できる新しいインターフェースを作成:(あなたがasync
を使用している場合やAsyncControllerActionInvoker
)次に
internal interface IActionConfigurator
{
void Configure(ControllerContext controllerContext, ActionDescriptor actionDescriptor);
}
を、私たちは私たちをフックするカスタムControllerActionInvoker
を作成します新しいインターフェイス:
internal sealed class CustomControllerActionInvoker : AsyncControllerActionInvoker
{
protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
{
var actionDescriptor = base.FindAction(controllerContext, controllerDescriptor, actionName);
var configurators = actionDescriptor.GetCustomAttributes(typeof(IActionConfigurator), true).Cast<IActionConfigurator>();
foreach (var configurator in configurators)
configurator.Configure(controllerContext, actionDescriptor);
return actionDescriptor;
}
}
は今、私たちが設定したカスタムDefaultControllerFactory
を実装する必要がController.ActionInvoker
:
ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
とカスタム属性に私たちのIActionConfigurator
インタフェースを実装しています:新しいコントローラのインスタンスので
internal sealed class IgnoreJsonActionConfiguratorAttribute : Attribute, IActionConfigurator
{
public void Configure(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
// Here we can configure action-specific stuff on the controller
var factories = ValueProviderFactories.Factories.Where(f => !(f is JsonValueProviderFactory)).ToList();
controllerContext.Controller.ValueProvider = new ValueProviderFactoryCollection(factories).GetValueProvider(controllerContext);
}
}
internal sealed class CustomControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
var instance = base.GetControllerInstance(requestContext, controllerType);
var controller = instance as Controller;
if (controller != null)
controller.ActionInvoker = new CustomControllerActionInvoker();
return instance;
}
}
最後に、我々は、スタートアップコードのデフォルトとして、当社のカスタムコントローラファクトリを設定します各リクエストで作成されるため、MVCがアクションをどのように処理するかを変更するために、コントローラにアクション固有の値を設定することができます。
[AcceptVerbs(HttpVerbs.Post)]
[IgnoreJsonActionConfigurator]
public async Task<ActionResult> Foo() { ... }
トリックをしたおかげで、!これは文書化されていない機能ですか、それとも私は何かを見逃しましたか? –
MVCには、デフォルトで値プロバイダファクトリのセットが含まれています。 MVC3では、デフォルトの1つとしてJsonValueProviderFactoryが含まれていました。上記のすべてのコードは、アプリケーションを見つけてアプリケーションの起動時に削除します。それを回避するもう1つの方法は、あなたのAjaxリクエストは、コンテンツタイプapplication/jsonのを使用していないことだったかもしれないが、私は値プロバイダーファクトリを削除すると、おそらくより正確であると感じています。 –
説明をありがとう。私はクエリーストリングやルートのようなもののプロバイダ工場があることに気づいていませんでした。私はModelBinderがそのすべてを処理していると仮定しました。 –