UpdateModel со словарем / Hashtable - PullRequest
1 голос
/ 30 августа 2010

Я пробовал кое-что из MVC, и мне было интересно, есть ли способ редактировать динамические поля. Поэтому, чтобы попробовать это, я добавил коллекцию ключей под названием CustomFields. Я пробовал и Hashtable и словарь.

По мнению я тогда писал:

<%:Html.TextBoxFor(model => model.CustomFields["x"])%>

Затем генерируется этот HTML:

<input id="CustomFields_x_" name="CustomFields[x]" type="text" value="" />

Похоже, я на правильном пути, и для этого есть некоторые функции. Но проблема в том, что когда я вызываю UpdateModel, он не привязывает значение, которое я записываю к этой коллекции ключей.

Это вообще возможно сделать? Нужно ли делать что-то особенное, чтобы решить это?

1 Ответ

2 голосов
/ 01 сентября 2010

Я вполне уверен, что есть встроенный способ справиться с этим, но я не смог его найти. Однако вы можете достичь желаемого с помощью следующей реализации 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() { };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...