2010-08-30 92 views
1

我尝试了一些MVC的东西,我想知道如果有一些方法来编辑动态字段。 所以要尝试这个,我添加了一个名为CustomFields的键控集合。我已经尝试了Hashtable和Dictionary。UpdateModel与字典/散列表

在视图然后我写道:

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

这则生成此HTML:

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

因此,它看起来像我在正确的道路,并有一些这方面的功能。但问题是,当我调用UpdateModel时,它不会绑定我写入该键控集合的值。

这甚至有可能吗?我需要做些特别的事情来解决它吗?

回答

2

我相当肯定有一个内置的处理方式,但我找不到它。但是,您可以使用以下IModelBinder实现完成您想要的任务。

为您的模型创建一个自定义活页夹。首先,我们将使用默认的模型绑定器来附加任何不属于您的字典的属性。

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() { }; 
注册粘结剂