uadrive réponse m'a pris une partie du chemin, mais il y avait encore quelques lacunes. Sans les données de l'entrée à l' new NameValueCollectionValueProvider()
, le modèle de classeur de lier le contrôleur à un modèle vide, de ne pas l' model
objet.
C'est très bien -- serialise votre modèle en tant que NameValueCollection
, et de passer ensuite que dans l' NameValueCollectionValueProvider
constructeur. Eh bien, pas tout à fait. Malheureusement, il ne fonctionne pas dans mon cas car mon modèle contient une collection, et l' NameValueCollectionValueProvider
ne joue pas bien avec les collections.
L' JsonValueProviderFactory
vient à la rescousse ici, cependant. Il peut être utilisé par l' DefaultModelBinder
aussi longtemps que vous spécifiez un type de contenu de "application/json
" et passer votre sérialisés objet JSON dans votre demande du flux d'entrée (Veuillez noter, parce que ce flux d'entrée est un flux de mémoire, c'est OK pour laisser undisposed, comme un flux de mémoire ne s'accroche pas à toutes les ressources externes):
protected void BindModel<TModel>(Controller controller, TModel viewModel)
{
var controllerContext = SetUpControllerContext(controller, viewModel);
var bindingContext = new ModelBindingContext
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => viewModel, typeof(TModel)),
ValueProvider = new JsonValueProviderFactory().GetValueProvider(controllerContext)
};
new DefaultModelBinder().BindModel(controller.ControllerContext, bindingContext);
controller.ModelState.Clear();
controller.ModelState.Merge(bindingContext.ModelState);
}
private static ControllerContext SetUpControllerContext<TModel>(Controller controller, TModel viewModel)
{
var controllerContext = A.Fake<ControllerContext>();
controller.ControllerContext = controllerContext;
var json = new JavaScriptSerializer().Serialize(viewModel);
A.CallTo(() => controllerContext.Controller).Returns(controller);
A.CallTo(() => controllerContext.HttpContext.Request.InputStream).Returns(new MemoryStream(Encoding.UTF8.GetBytes(json)));
A.CallTo(() => controllerContext.HttpContext.Request.ContentType).Returns("application/json");
return controllerContext;
}