Я вполне уверен, что есть встроенный способ справиться с этим, но я не смог его найти. Однако вы можете достичь желаемого с помощью следующей реализации IModelBinder.
Создайте пользовательский Binder для вашей модели. Сначала мы собираемся использовать связыватель моделей по умолчанию, чтобы прикрепить любые свойства, которые не являются вашим словарем.
public class CustomFieldsModelBinder : IModelBinder {
IDictionary<string, string> dictionary;
public CustomFieldsModelBinder() { }
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext) {
if (bindingContext == null)
throw new ArgumentNullException("bindingContext");
CustomFieldsModel returnValue;
returnValue = (CustomFieldsModel)ModelBinders.Binders.DefaultBinder.BindModel(
controllerContext,
bindingContext);
if (returnValue == null) {
returnValue = new CustomFieldsModel();
}
if (returnValue.CustomFields == null)
returnValue.CustomFields = new Dictionary<string, string>();
foreach (string name in DictionaryKeyNames(controllerContext, "CustomFields")) {
var postValue = controllerContext.HttpContext.Request.Form["CustomFields[" + name + "]"];
returnValue.CustomFields[name] = postValue;
}
return returnValue;
}
//this method will grab the [name]'s from the collection
protected virtual IList<string> DictionaryKeyNames(ControllerContext context, string prefix) {
IList<string> list = new List<string>();
Regex pattern = new Regex("^" + prefix + @"\[([^\]]+)\]");
foreach (var key in context.HttpContext.Request.Form.AllKeys) {
var match = pattern.Match(key);
if (match.Success && !list.Contains(match.Value)) {
list.Add(match.Groups[1].Value);
}
}
return list;
}
}
Как только вы это сделаете, вы можете зарегистрировать связующее в Global.asax
ModelBinders.Binders[typeof(CustomFieldsModel)] = new CustomFieldsModelBinder() { };