Как создать пользовательский механизм связывания модели, используя сигнатуру `BindModel (HttpActionContext actionContext ...`)? - PullRequest
25 голосов
/ 28 марта 2012

Мне нужно знать, как создать пользовательский IModelBinder в MVC 4, и он был изменен.

Новый метод, который должен быть реализован:

bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext);

Ответы [ 4 ]

28 голосов
/ 28 марта 2012

Есть 2 интерфейса IModelBinder:

  1. System.Web.Mvc.IModelBinder, что соответствует предыдущим версиям и не изменилось
  2. System.Web.Http.ModelBinding.IModelBinder, который используется веб-API и ApiController. Таким образом, в основном внутри этого метода вы должны установить actionContext.ActionArguments на соответствующие значения. Вы больше не возвращаете экземпляр модели.
24 голосов
/ 13 апреля 2012

Эта ссылка , предоставленная Стивом, дает полный ответ.Я добавляю это сюда для справки.На форумах asp.net кредит идет на дравву.

Сначала создайте класс, полученный из IModelBinder.Как говорит Дарин, обязательно используйте пространство имен System.Web.Http.ModelBinding, а не привычный эквивалент MVC.

public class CustomModelBinder : IModelBinder
{
    public CustomModelBinder()
    {
        //Console.WriteLine("In CustomModelBinder ctr");
    }

    public bool BindModel(
        HttpActionContext actionContext, 
        ModelBindingContext bindingContext)
    {
        //Console.WriteLine("In BindModel");
        bindingContext.Model = new User() { Id = 2, Name = "foo" };
        return true;
    }
}

Далее укажите поставщика, который действует как фабрика для вашего нового связующего, и любых других связующих, которые выможет добавить в будущем.

public class CustomModelBinderProvider : ModelBinderProvider
{
    CustomModelBinder cmb = new CustomModelBinder();
    public CustomModelBinderProvider()
    {
        //Console.WriteLine("In CustomModelBinderProvider ctr");
    }

    public override IModelBinder GetBinder(
        HttpActionContext actionContext,
        ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType == typeof(User))
        {
            return cmb;
        }

        return null;
    }
}

Наконец, включите в ваш Global.asax.cs следующее (например, Application_Start).

var configuration = GlobalConfiguration.Configuration;

IEnumerable<object> modelBinderProviderServices = configuration.ServiceResolver.GetServices(typeof(ModelBinderProvider));
List<Object> services = new List<object>(modelBinderProviderServices);
services.Add(new CustomModelBinderProvider());
configuration.ServiceResolver.SetServices(typeof(ModelBinderProvider), services.ToArray());

Теперь вы можете просто отменить новыйвведите в качестве параметра для ваших методов действия.

public HttpResponseMessage<Contact> Get([ModelBinder(typeof(CustomModelBinderProvider))] User user)

или даже

public HttpResponseMessage<Contact> Get(User user)
8 голосов
/ 13 февраля 2013

Даже простой способ добавить связыватель модели без ModelBinderProvider заключается в следующем:

GlobalConfiguration.Configuration.BindParameter(typeof(User), new CustomModelBinder());
3 голосов
/ 13 сентября 2012

Обновление пост-RC для поста Тодда:

Упрощено добавление провайдера вашей модели:

var configuration = GlobalConfiguration.Configuration;

configuration.Services.Add(typeof(ModelBinderProvider), new YourModelBinderProvider());
...