3
votes

I am sending a List<> to a View, and then turning that list into an array of hidden fields. This is being done using a partial view, to build the table.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BudgieMoneySite.Models.TransactionSplitLine>" %>
<tr>
    <td>
        <%=Model.Category %>
        <%=Html.HiddenFor(x => x.CategoryId)%>
    </td>
    <td>
        <%=Model.SubCategory %>
        <%=Html.HiddenFor(x => x.SubCategoryId)%>
    </td>
    <td>
        <%=Model.Amount %>
        <%=Html.HiddenFor(x => x.AmountValue)%>
    </td>

</tr>

I have have x number of rows.... so I am hoping I can get the values from the hidden fields as an array. I have a field in my model, defined as public string[] CategoryIds { get; set; }

(I think the issue may be around the hidden field being called 'CategoryId' and mu model wanting 'CategoryIds').

When rendered, I see I have a row which looks like this:

<tr>
<td>
    Medical
    <input id="TransactionSplitLines_2__CategoryId" name="TransactionSplitLines[2].CategoryId" type="hidden" value="6" />

</td>
<td>
    Over the Counter Medicines
    <input id="TransactionSplitLines_2__SubCategoryId" name="TransactionSplitLines[2].SubCategoryId" type="hidden" value="22" />
</td>
<td>
    111
    <input id="TransactionSplitLines_2__AmountValue" name="TransactionSplitLines[2].AmountValue" type="hidden" value="0" />
</td>

I am then trying to get the data back in the controller like this:

[HttpPost]
public ActionResult AccountTransaction(AccountTransactionView model)
{
    var reply = CreateModel(model);
    if (model.CategoryIds != null)
    {
        for (int i = 0; i < model.CategoryIds.Count(); i++ )
        {
            reply.TransactionSplitLines.Add(new TransactionSplitLine
                                                {
                                                    Amount = "100", 
                                                    Category = Services.CategoryServices.GetCategoryById(int.Parse(model.CategoryIds[i])).Description, 
                                                    SubCategoryId = model.SelectedCategoryId, 
                                                    SubCategory = Services.SubCategoryServices.GetSubCategoryById(model.SelectedSubCategoryId).Description
                                                });
        }
    }
    reply.TransactionSplitLines.Add(new TransactionSplitLine
                                        {
                                            Amount = model.Amount, 
                                            Category = Services.CategoryServices.GetCategoryById(model.SelectedCategoryId).Description, 
                                            SubCategory = Services.SubCategoryServices.GetSubCategoryById(model.SelectedSubCategoryId).Description, 
                                            CategoryId = model.SelectedCategoryId,
                                            SubCategoryId = model.SelectedSubCategoryId
                                        });
    return View("AccountTransaction", reply);
}

But CategoryIds is always null...

How can I reference the hidden fields, when their name is 'TransactionSplitLines[2].SubCategoryId' (Which is the 2nd row, I think). I think I have a naming issue, and am just getting tangled... but hopefully you can assit?

EDIT: Here's the AccountTransactionView class..

 public class AccountTransactionView
{
  public AccountTransactionView()
  {
      TransactionSplitLines = new List<TransactionSplitLine>();
  }

    [DisplayName("Bank Account")]
    public IEnumerable<SelectListItem> Accounts { get; set; }

    [DisplayName("Cost Center")]
    public IEnumerable<SelectListItem> CostCenters { get; set; }

    [DisplayName("Payee")]
    public IEnumerable<SelectListItem> Payees { get; set; }

    [DisplayName("Transaction Type")]
    public List<TransactionTypeView> TransactionTypes { get; set; }

    public int SelectedAccountId { get; set; }
    public int SelectedCostCenterId { get; set; }
    public int SelectedPayeeId { get; set; }
    [DisplayName("Category")]
    public int SelectedCategoryId { get; set; }
    [DisplayName("Sub Category")]
    public int SelectedSubCategoryId { get; set; }
    public int SelectedTransactionTypeId { get; set; }
    [DisplayName("Budget")]
    public int SelectedBudgetId { get; set; }

    [DisplayName("Transaction Date")]
    public DateTime TransactionDate { get; set; }
    [DisplayName("Transaction Date")]
    public string FormattedDateTime
    {
        get
        {
            return TransactionDate.ToString("dd/MM/yyyy");

        }
    }
    public int TransactionId { get; set; }
    public bool Deleted { get; set; }
    public List<TransactionSplitLine> TransactionSplitLines { get; set; }
    public string Amount { get; set; }

}
2
Can you send AccountTransactionView class?LukLed
@LukLed - I've added it to the post above.Craig
You can always add parameter IEnumerable<TransactionSplitLine> TransactionSplitLines, so you'd have public ActionResult AccountTransaction(AccountTransactionView model, IEnumerable<TransactionSplitLine> TransactionSplitLines)LukLed
I created extension method for this. Check this answer: stackoverflow.com/a/46318317/1341409Gh61

2 Answers

3
votes

You need to iterate through the collection to post it back to the controller:

@if (Model.Items != null)
{
    for (int i = 0; i < Model.Items.Length; i++)
    {
        @Html.HiddenFor(x => x.Items[i])
    }
}