Ответ Уадрива взял меня с пути, но все еще были некоторые пробелы.Без каких-либо данных на входе 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;
}