When my model has an IEnumerable<T> property implemented as an iterator (ie yield return ), MVC DefaultModelBinder cannot bind to this property when input values use square bracket syntax (for example, "Foo[0]" ).
Model Example:
namespace ModelBinderTest { using System.Collections.Generic; public class MyModel { private List<string> fooBacking = new List<string>(); public IEnumerable<string> Foo { get { foreach (var o in fooBacking) { yield return o;
Bad Example 1 :
namespace ModelBinderTest { using System; using System.Linq; using System.Web.Mvc; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] [CLSCompliant(false)] public class DefaultModelBinderTestIterator { [TestMethod] public void BindsIterator() {
The unit test above will update the Bar property of my model as ["bar"] without problems (with or without square brackets in the collection keys), but it will not be able to bind anything to the Foo property.
Does anyone know (at a low level) why introducing the IEnumerable property as an iterator will cause model binding to fail?
I do not really like workarounds 2 but rather some analysis, since I have exhausted my knowledge that the structure has come to this;)
1: A unit test was the easiest way to isolate the problem for SO, and not through the entire MVC sample application.
2: For example, I know that if I remove the square brackets from the input and reuse the same "Foo" key for all values, model binding will work. However, a real bad case requires square brackets, because each element in the collection is a complex type with its own sub-properties. Or another workaround: add the non-iterator IEnumerable<T> parameter to the action and assign this property directly inside the action. Ugh.Sub>
iterator asp.net-mvc ienumerable model-binding
Roatin marth
source share