Is there any way to disable the JSON ModelBinder in ASP.NET MVC 3 RC2?

旧巷老猫 提交于 2019-12-03 02:44:54

You can put the following in Application_Start in your Global.asax:

ValueProviderFactories.Factories.Remove(
            ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().First());

This assumes there is only one of that type (which by default there is), but it can easily be changed to work if there is more than one. I don't believe there is a cleaner way if that is what you are looking for.

I'm obviously pretty late in answering this, but I've developed a way to change the IValueProvider for a specific action in MVC5. I haven't gone through the effort of seeing if this is possible in MVC3 since this question is old, but I assume it is somewhat similar.

Disclaimer: It's not pretty.

First, we create a new interface we can implement in an attribute to make action-specific configurations:

internal interface IActionConfigurator
{
    void Configure(ControllerContext controllerContext, ActionDescriptor actionDescriptor);
}

Then, we create a custom ControllerActionInvoker (or AsyncControllerActionInvoker if you use async) to hook up our new interface:

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;
    }
}

Now, we have to implement a custom DefaultControllerFactory to set Controller.ActionInvoker:

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;
    }
}

Finally, we set our custom controller factory as the default in the startup code:

ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));

and implement our IActionConfigurator interface in a custom attribute:

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);
    }
}

Since a new Controller instance is created on each request, we are able to set action-specific values on the controller to modify how MVC processes the action.

[AcceptVerbs(HttpVerbs.Post)]
[IgnoreJsonActionConfigurator]
public async Task<ActionResult> Foo() { ... }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!