2012-03-28 4 views
24

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

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

bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext); 

ответ

27

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

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

Yesss, спасибо Дарин. –

+3

Также необходимо зарегистрировать заказное связующее устройство. ASP.Net Web API не имеет такого же способа, как MVC3. Проверьте [этот пост] (http://forums.asp.net/t/1773706.aspx/1), чтобы узнать, как это сделать в бета-версии MVC4. Нижняя часть ответа трудно понять, но обратите внимание, что вы установили его в 'global.asax.cs' с' GlobalConfiguration.Configuration.ServiceResolver.GetServices ... ' – Steve

24

This link, предоставленный Стивом, дает полный ответ. Я добавляю его здесь для справки. Кредит идет на dravva на форумах 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) 
+0

Я считаю, что до тех пор, пока вы явно используете [ModelBinder (typeof (CustomModelBinderProvider))] в вашем действии вам не нужен ModelBinderProvider. –

3

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

Добавление вашей модели поставщик связующий упрощена:

var configuration = GlobalConfiguration.Configuration; 

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

Это сработало для меня. Есть ли способ сделать это глобально, т. Е. Установить привязку модели по умолчанию? –

8

An даже простой способ добавить modelbinder без ModelBinderProvider:

GlobalConfiguration.Configuration.BindParameter(typeof(User), new CustomModelBinder()); 
+0

Это сработало отлично! По какой-то причине я не мог получить ни один из других примеров на этой странице для работы с MVC4. Интерфейс для ModelBinderProvider, похоже, изменился. Но удаление ModelBinderProvider и добавление этого кода в Application_Start отлично поработали! –