2012-03-28 29 views
24

Necesito saber cómo crear un IModelBinder personalizado en MVC 4 y ha sido cambiado.MVC 4 ModelBinder

El nuevo método que tiene que ser implementado es:

bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext); 

Respuesta

27

Hay 2 interfaces IModelBinder:

  1. System.Web.Mvc.IModelBinder que es el mismo que en las versiones anteriores y no ha cambiado
  2. System.Web.Http.ModelBinding.IModelBinder que es utilizado por la API web y el ApiController. Así que, básicamente, dentro de este método debe establecer el actionContext.ActionArguments en los valores correspondientes. Ya no devuelve una instancia modelo.
+0

Yesss, gracias Darin. –

+3

También hay que registrar un archivador de modelo personalizado. ASP.Net Web API no tiene la misma forma que MVC3. Consulte [esta publicación] (http://forums.asp.net/t/1773706.aspx/1) para ver cómo hacerlo en MVC4 Beta. La parte inferior de la respuesta es difícil de entender, pero tenga en cuenta que la configuró en 'global.asax.cs' con' GlobalConfiguration.Configuration.ServiceResolver.GetServices ... ' – Steve

24

This link, proporcionado por Steve, proporciona una respuesta completa. Lo estoy agregando aquí para referencia. El crédito va a dravva en los foros de asp.net.

Primero, crea una clase derivada de IModelBinder. Como dice Darin, asegúrese de usar el espacio de nombres System.Web.Http.ModelBinding y no el conocido MVC equivalente.

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

A continuación, proporcionar un proveedor, que actúa como una fábrica para su nueva carpeta, y cualquier otros aglutinantes se puede añadir en el futuro.

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

Por último, se incluyen los siguientes en su Global.asax.cs (por ejemplo, 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()); 

Ahora, puede simplemente retrasar el nuevo tipo como parámetro para sus métodos de acción.

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

o incluso

public HttpResponseMessage<Contact> Get(User user) 
+0

Creo que, siempre que use explícitamente [ModelBinder (typeof (CustomModelBinderProvider))] en su acción, no necesita el ModelBinderProvider. –

3

una actualización posterior a RC a cargo de Todd:

Adición de su proveedor de ligante modelo se ha simplificado:

var configuration = GlobalConfiguration.Configuration; 

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

Esto funcionó para mí. ¿Hay alguna forma de hacerlo globalmente, es decir, establecer el archivador de modelo predeterminado? –

8

Una siquiera forma sencilla de añadir un encuadernador sin un ModelBinderProvider es este:

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

¡Esto funcionó a la perfección! Por alguna razón, no pude obtener ninguno de los otros ejemplos en esta página para trabajar con MVC4. La interfaz para ModelBinderProvider parece haber cambiado. ¡Pero eliminar el ModelBinderProvider y agregar este código al Application_Start funcionó de maravilla! –

Cuestiones relacionadas