ASP.NET MVC3 - Динамические формы (ModelBind к словарю <строка, строка> или NameValueCollection) - Как? - PullRequest
1 голос
/ 02 февраля 2012

Допустим, у меня есть форма, в которой могут быть новые текстовые вводы, созданные в JavaScript во время выполнения. И я хочу связать значения с коллекцией NameValueCollection (или словарем). Собственно ли 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));
}

Нужно ли мне делать свою собственную модель связующего? Или я просто неправильно называю поля ввода?

1 Ответ

1 голос
/ 02 февраля 2012

Я не думаю, что связыватель модели 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);
            }
        }
    }
}
...