ASP.NET MVC3-动态表单(ModelBind to a Dictionary<;string、string

本文关键字:string Dictionary lt to MVC3- NET 动态 表单 ModelBind ASP | 更新日期: 2023-09-27 18:22:10

假设我有一个表单,它可以在运行时用JavaScript创建新的文本输入。我想将这些值绑定到NameValueCollection(或Dictionary)。ASP.NET MVC3本身是否允许这样做?

换句话说,我该如何让它发挥作用

假设这是HTML表单…

<!-- if someone posted this form -->
<form action="MyExample">
    <input type="hidden" name="id" value="123" />
    <input type="text" name="things.abc" value="blah" />
    <input type="text" name="things.def" value="happy" />
    <input type="text" name="things.ghi" value="pelicans" />
    <input type="submit" />
</form>

这就是控制器中的"动作"。。。

public ActionResult MyExample(int id, NameValueCollection things)
{
    // At this point, `things["abc"]` should equal `"blah"`
    return Content(string.Format("Things has {0} values.", things.Count));
}

我需要自己制作模型活页夹吗?还是我只是错误地命名了输入框?

ASP.NET MVC3-动态表单(ModelBind to a Dictionary<;string、string

我不认为默认的ASP.NET MVC3模型绑定器能做到这一点,所以我创建了以下助手类。它是有效的,我只是不想在DefaultModelBinder已经处理这个问题的情况下这样做。

我暂时不会把它标记为答案,希望有人能告诉我如何在没有自定义类的情况下正确工作。但对于那些有同样需求的人,这里有代码。

Global.asax.cs

// Add this line in the Application_Start() method in the Global.asax.cs
ModelBinders.Binders.DefaultBinder = new NameValueAwareModelBinder();

自定义模型活页夹

using System.Collections.Specialized;
using System.Web.Mvc;
namespace Lil_Timmys_Example.Helpers
{
    public class NameValueAwareModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelMetadata.ModelType == typeof(NameValueCollection))
            {
                var result = new NameValueCollection();
                string prefix = bindingContext.ModelName + ".";
                var queryString = controllerContext.HttpContext.Request.QueryString;
                foreach (var key in queryString.AllKeys)
                {
                    if (key.StartsWith(prefix))
                    {
                        result[key.Substring(prefix.Length)] = queryString.Get(key);
                    }
                }
                var form = controllerContext.HttpContext.Request.Form;
                foreach (var key in form.AllKeys)
                {
                    if (key.StartsWith(prefix))
                    {
                        result[key.Substring(prefix.Length)] = form.Get(key);
                    }
                }
                return result;
            }
            else
            {
                return base.BindModel(controllerContext, bindingContext);
            }
        }
    }
}