uadrive的回答使我有些困惑,但是仍然存在一些差距。在的输入中没有任何数据时new NameValueCollectionValueProvider()
,模型绑定器会将控制器绑定到一个空模型,而不是该model
对象。
很好-只需将模型序列化为NameValueCollection
,然后将其传递给NameValueCollectionValueProvider
构造函数即可。好吧,不完全是。不幸的是,在我的情况下,它不起作用,因为我的模型包含一个集合,并且NameValueCollectionValueProvider
不能很好地与集合配合使用。
在JsonValueProviderFactory
来这里的营救,虽然。它可以通过使用DefaultModelBinder
只要您指定的内容类型的"application/json
“,并通过你的序列化JSON对象到您的请求的输入流(请注意,因为此输入流是一个内存流,这是确定要离开它未予处置,作为存储器流不占用任何外部资源):
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;
}