Я закончил тем, что углубился в создание своего собственного связывателя модели, который выполняет рекурсивное связывание.До тех пор, пока имена свойств не используются повторно, что в любом случае не произойдет в моих моделях, это устраняет мою проблему, заключающуюся в том, чтобы не раскрывать имена свойств классов вложенных моделей.
Так что теперь у меня естьследующая структура класса:
public class ModelA
{
public string Test { get; set; }
public string Name { get; set; }
}
public class ModelB
{
public int? SomeInteger { get; set; }
public int? TestInteger { get; set; }
}
public class ViewModel
{
public ModelA ModelA { get; set; }
public ModelB ModelB { get; set; }
}
И теперь действие выглядит следующим образом:
public ActionResult Index(ViewModel model)
{
return Content("ok");
}
, что позволит мне использовать следующую строку запроса без раскрытия уродливых имен свойств:
index?Test=Hi&SomeInteger=7&Name=Yep&TestInteger=72
Конечно, я не тестировал это в течение длительного периода времени, поэтому я не знаю, какие проблемы скрываются за углом, но все вложенные модели теперь правильно заполнены данными изСтрока запроса и классы модели могут быть легко использованы повторно:)
public class RecursiveModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var model = base.BindModel(controllerContext, bindingContext);
if (model != null)
{
var properties = bindingContext.ModelType.GetProperties().Where(x => x.PropertyType.IsClass && !x.PropertyType.Equals(typeof(string)) );
foreach(var property in properties)
{
var resursiveBindingContext = new ModelBindingContext(bindingContext)
{
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, property.PropertyType)
};
var recursiveModel = BindModel(controllerContext, resursiveBindingContext);
property.SetValue(model, recursiveModel);
}
}
return model;
}
}