Reputation: 494
I am just attempting to bind a collection from a form post. My collection in the model is a different name than what I'm trying to bind to, which my be the cause of the issue. I had this working, and then it stopped. I cannot find what changed to make it stop.
I thought my question was similar to this one: ASP.NET MVC5: Want to update several items in Collection with model binding
And I have read this a few times (Scott Hanselman can be counted on to give a clear picture of such things): http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
Here's some code:
public class AttestModel
{
public Account Account { get; set; }
public List<AccountSimpleDetail> AccountSimpleDetails { set; get; }
}
public class AccountSimpleDetResponseModel
{
public int AccountSimpleDetailId { get; set; }
public int AnswerId { get; set; }
}
public partial class AccountSimpleDetail :
{
public int AccountSimpleDetailId { get; set; }
public int? SaqSimpleQuestionId { get; set; }
public int? SaqAnswerId { get; set; }
...More fields go on here
}
In the View I have:
@for (var i = 0; i < Model.AccountSimpleDetails.Count(); i++)
{
@Html.HiddenFor(x => x.AccountSimpleDetails[i].AccountSimpleDetailId)
@Html.HiddenFor(x => x.AccountSimpleDetails[i].AnswerId)
}
I have some Javascript to handle clicking on a bunch of buttons in the browser which sets the AnswerId in the hidden fields. This is working fine.
The markup produced looks like this:
<input data-val="true" data-val-number="The field AccountSimpleDetailId must be a number." data-val-required="The AccountSimpleDetailId field is required." id="AccountSimpleDetails_1__AccountSimpleDetailId" name="AccountSimpleDetails[1].AccountSimpleDetailId" type="hidden" value="71" />
<input data-val="true" data-val-number="The field AnswerId must be a number." id="AccountSimpleDetails_1__AnswerId" name="AccountSimpleDetails[1].AnswerId" type="hidden" value="1" />
The method signature looks like this:
public ActionResult Attest(int id, List<AccountSimpleDetResponseModel> AccountSimpleDetails)
What I used previously (which stopped working) is:
public ActionResult Attest(int id, [Bind(Prefix = "AccountSimpleDetails")] List<AccountSimpleDetResponseModel> simpleDetails)
The result of the bind is always null.
I know when I get to the point where I try something, it doesn't work, I try something else... it simply means I am missing some fundamental point. Thank you for your time.
Here is the post request (Raw from Watchlist):
AccountSimpleDetails%5b1%5d.AccountSimpleDetailId=165&AccountSimpleDetails%5b1%5d.AnswerId=1&AccountSimpleDetails%5b2%5d.AccountSimpleDetailId=166&AccountSimpleDetails%5b2%5d.AnswerId=1&AccountSimpleDetails%5b3%5d.AccountSimpleDetailId=167&AccountSimpleDetails%5b3%5d.AnswerId=1&AccountSimpleDetails%5b4%5d.AccountSimpleDetailId=168&AccountSimpleDetails%5b4%5d.AnswerId=1&DXScript=1_171%2c1_94%2c1_93%2c17_33%2c17_2%2c1_152%2c1_164%2c1_91%2c1_156%2c1_101%2c17_7%2c1_154%2c1_103%2c1_102%2c17_8%2c1_114%2c1_121%2c1_169%2c1_138%2c1_170%2c1_124%2c17_9%2c1_163%2c1_162%2c1_147%2c17_32%2c1_157%2c1_98%2c1_125%2c1_104%2c1_166%2c1_139%2c17_13%2c1_97%2c1_141%2c1_142%2c17_15%2c1_155%2c1_143%2c1_144%2c17_16%2c17_17%2c1_126%2c17_11%2c1_146%2c1_149%2c17_20%2c1_160%2c17_22%2c1_158%2c1_153%2c1_161%2c17_25%2c1_165%2c17_28%2c17_31%2c1_100%2c5_5%2c5_4%2c4_11%2c4_10%2c4_6%2c4_7%2c4_9%2c17_14%2c4_12%2c1_113%2c1_116%2c4_13%2c4_14%2c1_110%2c1_112%2c1_137%2c17_12%2c1_159%2c7_49%2c7_47%2c7_51%2c17_21%2c1_105%2c1_108%2c1_117%2c17_0%2c1_120%2c1_106%2c17_1%2c1_107%2c17_3%2c1_109%2c1_122%2c17_5%2c1_145%2c1_119%2c17_18%2c17_19%2c1_118%2c17_29%2c1_123%2c10_2%2c10_1%2c10_3%2c10_4%2c17_4%2c9_23%2c9_22%2c9_24%2c17_24%2c9_13%2c9_10%2c9_8%2c17_23%2c9_12%2c9_9%2c9_15%2c9_11%2c1_96%2c8_10%2c8_17%2c8_24%2c8_26%2c8_9%2c8_12%2c8_13%2c8_18%2c17_26%2c8_21%2c8_23%2c8_22%2c8_16%2c8_19%2c8_20%2c8_14%2c8_15%2c8_25%2c8_11%2c6_12%2c17_30%2c16_16%2c16_18%2c16_14%2c16_11%2c16_19%2c16_6%2c16_15%2c16_8%2c16_12%2c16_13%2c16_7%2c17_27%2c16_17&DXCss=http%3a%2f%2ffonts.googleapis.com%2fcss%3ffamily%3dOpen%2bSans%3a300%2c400%2c600%2c700%2c800%257CShadows%2bInto%2bLight%2c%2fContent%2fbootstrap.min.css%2c%2fContent%2fMainSite.css%2c%2fContent%2fSiteAdjustments.css%2c%2fContent%2ffont-awesome.min.css%2c1_12%2c1_14%2c0_863%2c0_859%2c1_10%2c0_695%2c1_5%2c0_697%2c0_703%2c0_706%2c0_823%2c0_813%2c0_861%2c0_709%2c4_2%2c0_711%2c5_1%2c0_794%2c0_776%2c0_778%2c7_1%2c7_0%2c1_1%2c0_671%2c9_18%2c9_19%2c9_21%2c9_20%2c0_888%2c9_17%2c0_890%2c0_790%2c8_2%2c0_792%2c8_0%2c0_810%2c6_2%2c0_812%2c0_796%2c16_2%2c0_798
Upvotes: 0
Views: 930
Reputation: 494
I have this:
@for (int x = 0; x < Model.AccountSimpleDetails.Count(); x++)
{
<span>@x</span>
}
And it returns: 1,2, 3
That is the reason for the parsing issues as Stephen pointed out. So that's the real issue.
Thanks
Upvotes: 0
Reputation:
You binding your controls to properties of AttestModel
so just post back the model
public ActionResult Attest(AttestModel model)
and the AccountSimpleDetails
property will be correctly bound to the collection. However looking at your edited post request, it appears that the indexers are starting at 1
, not 0
(i.e. the first one is AccountSimpleDetails[1].AccountSimpleDetailId=165...
. Do you have any javascript that deletes items in the collection? If so it will not bind the collection because indexers are zero based (and must be consecutive) so you will need to add an additional control for the index property.
Upvotes: 2