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);
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);
Hay 2 interfaces IModelBinder:
System.Web.Mvc.IModelBinder
que es el mismo que en las versiones anteriores y no ha cambiadoSystem.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.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)
Creo que, siempre que use explícitamente [ModelBinder (typeof (CustomModelBinderProvider))] en su acción, no necesita el ModelBinderProvider. –
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());
Esto funcionó para mí. ¿Hay alguna forma de hacerlo globalmente, es decir, establecer el archivador de modelo predeterminado? –
Una siquiera forma sencilla de añadir un encuadernador sin un ModelBinderProvider es este:
GlobalConfiguration.Configuration.BindParameter(typeof(User), new CustomModelBinder());
¡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! –
Yesss, gracias Darin. –
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