0

I have a for loop set up currently that works. However, the issue comes about when I try to go back to the page it comes up with this error. I am trying to get it to initially present two references that they need to fill out and if they would like to add up to two additional references for this page for a total of 4 people. This is the code I am currently working with. This is the page View:

    <div id="reference-list">
        @for (int i = 0; i < Model.Order.References.Count; i++)
        {
            <div class="reference nomination-person" id="reference-@i">

                    <h3>Reference @(i+1)</h3>

                    <div class="person-attribute">
                        @Html.LabelFor(m => m.Order.References[i].Prefix)
                        @Html.DropDownListFor(m => m.Order.References[i].Prefix, new SelectList(prefixes))
                    </div>

                    <div class="person-attribute">

                        @Html.LabelFor(m => m.Order.References[i].FirstName)
                        @Html.TextBoxFor(m => m.Order.References[i].FirstName)
                        @Html.ValidationMessageFor(m => m.Order.References[i].FirstName)
                    </div>

                    <div class="person-attribute">
                        @Html.LabelFor(m => m.Order.References[i].MiddleName)
                        @Html.TextBoxFor(m => m.Order.References[i].MiddleName)
                    </div>

                    <div class="person-attribute">
                        @Html.LabelFor(m => m.Order.References[i].LastName)
                        @Html.TextBoxFor(m => m.Order.References[i].LastName)
                        @Html.ValidationMessageFor(m => m.Order.References[i].LastName)
                    </div>

                    <div class="person-attribute">
                        @Html.LabelFor(m => m.Order.References[i].Suffix)
                        @Html.DropDownListFor(m => m.Order.References[i].Suffix, new SelectList(suffixes))
                    </div>

                    <div class="person-attribute">
                        @Html.LabelFor(m => m.Order.References[i].Company)
                        @Html.TextBoxFor(m => m.Order.References[i].Company)
                    </div>

                    <div class="person-attribute">
                        @Html.LabelFor(m => m.Order.References[i].EmailAddress)
                        @Html.TextBoxFor(m => m.Order.References[i].EmailAddress)
                        @Html.ValidationMessageFor(m => m.Order.References[i].EmailAddress)
                    </div>

                    <div class="person-attribute">
                        @Html.LabelFor(m => m.Order.References[i].Telephone)
                        @Html.TextBoxFor(m => m.Order.References[i].Telephone)
                        @Html.ValidationMessageFor(m => m.Order.References[i].Telephone)
                    </div>

            </div>
        }
    </div>
    <input type="hidden" name="n-references" id="n-references" value="0" />


    <div id="add-reference">Add Reference</div>

The controller

    private OrderData GetReferencesData(OrderData data, HttpRequestBase request)
    {
         data.References = new List<Person>();
        /* Since there can be many references, iterate along all and create individual 
         * persona objects for each */

        for (int i = 0; i <= request["n-references"].ToInt(); i++)
        {
            data.References.Add(new Person
            {
                Prefix = request["Order.Prefix-" + i] ?? "",
                Suffix = request["Order.Suffix-" + i] ?? "",
                FirstName = request["Order.FirstName-" + i] ?? "",
                MiddleName = request["Order.MiddleName-" + i] ?? "",
                LastName = request["Order.LastName-" + i] ?? "",
                Company = request["Order.Company-" + i] ?? "",
                Telephone = request["Order.Telephone-" + i] ?? "",
                EmailAddress = request["Order.EmailAddress-" + i] ?? ""
            });
        }

        return data;
    }

While in the model it simply has public List<Person> References;

race155
  • 23
  • 7
  • Try to change the end condition of the for loop to `@for (int i = 1; i < Model.Order.References.Count(); i++)` – Abdul Hadi Jun 22 '16 at 22:22
  • Would that not allow them to add more than 4 references at a time? The reasoning behind putting in 4 was so that it would not allow for more than that to be added to the page. – race155 Jun 22 '16 at 22:53
  • Despite your claim that _currently that works_ - it never will bind correctly. You need to initialize your objects in the controller before you pass the model to the view and use `for (int i = 0; i <= Model.Order.References.Count; i++) { @Html.DropDownListFor(m => m.Order.References[i].Prefix, ....)` etc. If you then want to dynamically add more objects in the view, refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –  Jun 23 '16 at 01:02
  • @StephenMuecke I updated the code to what I have tried. You stated that I needed to initialize my object in the controller but I'm not quite sure what you mean by that so I included my controller in as well. – race155 Jul 01 '16 at 19:58
  • Not clear what your trying to do in the edited code (your `GetReferencesData()` method makes no sense and the Request will never contain any values such as `request["Order.Prefix-" + i]` anyway). In the controller, initialize you model and add 2 default objects , for example `model.Order.References.Add(new Reference());` and return that model to the view. –  Jul 02 '16 at 03:09
  • Then refer the answers [here](http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796) and [here](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) for how to dynamically add additional items to the collection –  Jul 02 '16 at 03:09

1 Answers1

0

Your m.order.references has less than 4 elements in it. so when you hit 3 or 4 on your index, it goes outside of the Reference array bounds and gives you an error. You should check the length of m.order.references before you try accessing spots in your array

Edit m.order.references is an list/array (for our purposes these are interchangeable), this object will have a finite amount of items in it for our example lets say it has 3 items. When you iterate over the list, if you try accessing an item in spot for m.order.references[4] you will get an out of range exception. This occurs because there is no item in position 4. What you need to do would be to

for(int i = 0; i <= m.order.references.count; i++) if you want to gaurentee that they can only have 4 references you will need to change your architecture to have a new references array and an existing references array(or something, because your current design doesn't support this)

gh9
  • 8,245
  • 8
  • 53
  • 89
  • I don't think I quite understand what you are saying. Could you elaborate more on your last sentence? – race155 Jun 22 '16 at 20:47