1

I am using C#, MVC 3 with razor The list is null in post when using the surounded if-statement. It works fine without the if. What I need is the list to have all the values in from the textboxes.

for (var i = 0; i < Model.Budget.BudgetRader.Count; i++)
    {
        if (Model.Budget.BudgetRader[i].Konto != -1) { 
            <tr>
                <td>@Html.TextBoxFor(x => x.Budget.BudgetRader[i].BudgetBelopp)</td>
            </tr>
        }
    }
n3tx
  • 429
  • 2
  • 10
  • 23

3 Answers3

2

The reason it doesn't work is described by Phil Hack.

An indexed collection needs index values for 0 and up increased by 1 and not skipping any. Therefor the binding doesn't work when you skip some rows with the if statement. Add a specific indexer i and if your rows need to be unique add a hidden field Id or similar. See updated example below.

int i = 0;
foreach (var rad in Model.Budget.BudgetRader)
{
    if (rad.Konto != -1)
    {
        <tr>
            <td>@Html.HiddenFor(x => x.Budget.BudgetRader[i].Id)</td>
            <td>@Html.TextBoxFor(x => x.Budget.BudgetRader[i++].BudgetBelopp)</td>
        </tr>
    }
    else
    {
        //...
    }
}

The following stack overflow is also good information: https://stackoverflow.com/a/8896840/455904

Community
  • 1
  • 1
Fredrik Ljung
  • 1,445
  • 13
  • 28
  • problem is that i need to add an label if konto = -1 so it will be an else statement as well and then it does not work to only get the values not cotaining -1 – n3tx Nov 12 '12 at 21:36
  • i read about custom model binding, but need help with writing one for this case. I have never used Custom Model Binding. So I would appreciate if some one can show me. – n3tx Nov 12 '12 at 21:37
  • Updated my answer. As for custom model binding I haven't tried it but the following seems a descent primer: http://buildstarted.com/2010/09/12/custom-model-binders-in-mvc-3-with-imodelbinder/ – Fredrik Ljung Nov 12 '12 at 21:55
  • I find it very weird .. it works if I not use any if statement, but when I do the list in httpPost is null. – n3tx Nov 12 '12 at 22:07
  • Updated again. The if breaks the indexer in the binding. Read answer and links for more info. – Fredrik Ljung Nov 12 '12 at 23:30
1

Try using the explicit Index value for each item. This allows you to have non-sequential indexes in your collections:

for (var i = 0; i < Model.Budget.BudgetRader.Count; i++)
{
    if (Model.Budget.BudgetRader[i].Konto != -1) { 
        <tr>
            <td>
                <input type="hidden" name="Budget.BudgetRader.Index" value="@i" /> 
                @Html.TextBoxFor(x => x.Budget.BudgetRader[i].BudgetBelopp)
            </td>
        </tr>
    }
}

Here's a similar answer: https://stackoverflow.com/a/8598287/1373170

I'm not sure if Budget.BudgetRader.Index is the correct name, since it should be the same name as your collection. If you post your current html output I'll correct it if necessary.

Community
  • 1
  • 1
Pablo Romeo
  • 11,298
  • 2
  • 30
  • 58
  • Do you know how/if I can get this to work with an Custom Model Binder ? – n3tx Nov 13 '12 at 20:34
  • Are you sure you don't want to try the "index" approach which is very easy and already part of MVC? It's really as straightforward as I just wrote above. Just specify the ".Index" for each and your set. – Pablo Romeo Nov 13 '12 at 22:50
  • I mention that because I think a custom binder might be overkill for this type of situation, that mvc can handle on its own. – Pablo Romeo Nov 13 '12 at 23:08
  • Yea, I think you are right. But now i'm just curious about Custom Binding. Do you know how it would look/work for this scenario ? – n3tx Nov 14 '12 at 07:25
1

Try doing something like this:

for (var i = 0; i < Model.Budget.BudgetRader.Count; i++)
{
    if (Model.Budget.BudgetRader[i].Konto != -1) { 
        <tr>
            <td>@Html.TextBoxFor(x => x.Budget.BudgetRader[i].BudgetBelopp)</td>
        </tr>
    }
    else
    {
        @Html.HiddenFor(x => x.Budget.BudgetRader[i].BudgetBelopp)
    }
}
Ivo
  • 8,172
  • 5
  • 27
  • 42
  • The drawback of using hidden fields for this, is that maybe that is sensitive data that the user should NOT modify. With hidden fields, you can ultimately edit it through the DOM, and end up manually editing things the user should not have access to. – Pablo Romeo Nov 13 '12 at 00:29
  • But you can anyway do that if you just create the post. The security issue is in the solution itself as it let you post as many items in that array as you want. The validation should come in the server side. – Ivo Nov 13 '12 at 00:30
  • I believe @PabloRomeo's answer is the standard MVC way – Ivo Nov 17 '12 at 19:33