简体   繁体   中英

ASP.Net MVC Hidden field not working as expected

I have maybe a strange requirement, but I thought implementing it would be easy.

I pass a List<> into a View. Within the view, I 'foreach' though the list, and build a Table. Within the table, I need to add hidden fields, so that I can get the values back on the post.

However, I am finding that when I use Html.Hidden, the field isn't rendered. In the view source, there is no mention of the fields...

        <table width="600">
        <tr class="headerRow">
            <td>
                Category
            </td>
            <td>
                Sub Category
            </td>
            <td>
                Amount
            </td>
        </tr>
        <% 
            if (Model.TransactionSplitLines != null)
            {
                foreach (var line in Model.TransactionSplitLines)
                {%>

        <tr>
            <td>
                <%=line.Category%>                
                <%=Html.Hidden("CategoryId", line.CategoryId.ToString()) %>

            </td>
            <td>
                <%=line.SubCategory%>
            </td>
            <td>
                <%=line.Amount%>
            </td>
        </tr>
        <%
            }
        } %>
    </table>
</div>
<input type="submit" value="Save" />

When I am then hoping to do is have an array of CategoryId, which I can read within the controller on the Action event.

I believe this would be generating multiple fields with the same ID (CategoryID), have you tried not using the Html.Helper and simply replacing it with this:

<input type='hidden' value='<%= line.CategoryId.ToString()%>' />

However - if you need to grab them by some type of ID - you could add a class inside there and use jQuery to pull all of your values:

<input class='CategoryId' type='hidden' value='<%=line.CategoryId.ToString()%>'/>

Then just use a $('.CategoryId').each() function to populate your list and POST it to your controller.

Personally I would use an editor template for this:

<% using (Html.BeginForm()) { %>
    <table width="600">
        <thead>
            <tr class="headerRow">
                <th>Category</th>
                <th>Sub Category</th>
                <th>Amount</th>
            </tr>
        </thead>
        <tbody>
            <%= Html.EditorFor(x => x.TransactionSplitLines) %>
        </tbody>
    </table>
    <input type="submit" value="Save" />
<% } %>

and then have a corresponding editor template ( ~/Views/Shared/EditorTemplates/TransactionSplitLine.ascx ):

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

Now not only that your view are much more readable but editor templates will take care of generating proper names for your hidden fields so that you can bind your model back:

[HttpPost]
public ActionResult Index(SomeViewModel model)
{
    // TODO: model.TransactionSplitLines should be properly bound 
    // at least the CategoryId property because it's the only one 
    // you are sending in the post
    ...
}

where SomeViewModel looks like this:

public class SomeViewModel 
{
    public IEnumerable<TransactionSplitLine> TransactionSplitLines { get; set; }
}

and:

public class TransactionSplitLine
{
    public string CategoryId { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM