Ho bisogno di sapere come creare un IModelBinder
personalizzato in MVC 4 ed è stato modificato.MVC 4 ModelBinder
Il nuovo metodo che deve essere implementato è:
bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext);
Ho bisogno di sapere come creare un IModelBinder
personalizzato in MVC 4 ed è stato modificato.MVC 4 ModelBinder
Il nuovo metodo che deve essere implementato è:
bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext);
Ci sono 2 interfacce IModelBinder:
System.Web.Mvc.IModelBinder
che è la stessa come nelle versioni precedenti e non è cambiatoSystem.Web.Http.ModelBinding.IModelBinder
che viene utilizzato dall'API Web e dall'ApiController. Quindi in pratica all'interno di questo metodo devi impostare lo actionContext.ActionArguments
sui valori corrispondenti. Non si restituisce più un'istanza di modello.This link, fornito da Steve, fornisce una risposta completa. Lo sto aggiungendo qui per riferimento. Il merito va a dravva nei forum di asp.net.
Innanzitutto, creare una classe derivata da IModelBinder
. Come dice Darin, assicurati di utilizzare lo spazio dei nomi System.Web.Http.ModelBinding
e non l'equivalente MVC familiare.
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;
}
}
successivo, fornire un fornitore, che agisce come una fabbrica per il nuovo legante, ed eventuali altri leganti è possibile aggiungere in 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;
}
}
Infine, includono quanto segue nel Global.asax.cs (ad esempio, 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());
Ora, è possibile delare il nuovo tipo come parametro per i metodi di azione.
public HttpResponseMessage<Contact> Get([ModelBinder(typeof(CustomModelBinderProvider))] User user)
o anche
public HttpResponseMessage<Contact> Get(User user)
Credo, purché si utilizzi esplicitamente [ModelBinder (typeof (CustomModelBinderProvider))] nella tua azione, non hai bisogno del ModelBinderProvider. –
Un aggiornamento messaggio RC al post di Todd:
Aggiungere il vostro fornitore binder modello è stato semplificato:
var configuration = GlobalConfiguration.Configuration;
configuration.Services.Add(typeof(ModelBinderProvider), new YourModelBinderProvider());
Questo ha funzionato per me. C'è un modo per farlo a livello globale, cioè impostare il modello predefinito di raccoglitore? –
Un anche modo semplice per aggiungere un modelbinder senza ModelBinderProvider è questo:
GlobalConfiguration.Configuration.BindParameter(typeof(User), new CustomModelBinder());
Questo ha funzionato perfettamente! Per qualche ragione non sono riuscito a far funzionare nessuno degli altri esempi su questa pagina con MVC4. L'interfaccia per ModelBinderProvider sembra essere cambiata. Ma rimuovere ModelBinderProvider e aggiungere questo codice a Application_Start ha funzionato alla grande! –
Sì, grazie Darin. –
È inoltre necessario registrare un raccoglitore modello personalizzato. L'API Web ASP.Net non ha lo stesso metodo di MVC3. Controlla [questo post] (http://forums.asp.net/t/1773706.aspx/1) per vedere come farlo in MVC4 Beta. La parte inferiore della risposta è difficile da capire, ma si noti che è stata impostata in 'global.asax.cs' con' GlobalConfiguration.Configuration.ServiceResolver.GetServices ... ' – Steve