rigamonk
rigamonk

Reputation: 1181

MVC passing the selected object from a List view page

I have a little serach box that returns results from a database. That works fine. The results are in a List page and display correctly. However, I need to take the selected object and pass it to my controller. I am getting NULL values when I debug it, and an empty results page. Here is the model:

public class CodeSnip
{
    public short Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Code { get; set; }
    public LangType Language { get; set; }
    public string Creator { get; set; }

}

public class ListOfCodeSnips : List<CodeSnip>
{
    public CodeSnip CodeSnip { get; set; }
}

public enum LangType
{
    CSharp,                
    css,
    HTML,
    JavaScript,
    Perl,
    PHP,
    Python,
    Ruby,
    SQL,
    VB,
    XML,
    Other
}

Here is the controller method (which does nothing atm):

    [HttpPost]
    public ActionResult Display(CodeSnip snip)
    {
        return View(snip);
    }

Here is what I have for a view. Again, it posts only NULLS for the object values:

@model Models.ListOfCodeSnips

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.CodeSnip.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CodeSnip.Description)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CodeSnip.Language)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CodeSnip.Creator)
        </th>
    </tr>

    @using (Html.BeginForm("Display", "Home", FormMethod.Post))
    {


    foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Title)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Language)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Creator)
        </td>
        <td>
            <input type="submit" value ="Display"/>
        </td>
    </tr>
        }
    }
</table>

so, in short, what I want to do is take the selected model-item from the view and pass it into my controllers Display method, but as I said, all I get are nulls. I have looked around and all i find are examples f how to pass a List of objects. I tried monkeying with those, but got nothing.

Thanks for your time.

Upvotes: 0

Views: 2184

Answers (2)

Georg Patscheider
Georg Patscheider

Reputation: 9463

There are two problems with your code:

1) You do not render any <input> elements in which you send the selected values back to the controller. Use Html.HiddenFor or Html.EditorFor in addition to Html.DisplayFor.

2) In order for the MVC Modelbinder to be able to bind your list, use a for loop instead of foreach.

See also MVC Form submit not transferring the updated model back to action method for List

for (var i = 0; i < Model.Count(); i++) {
    <tr>
        <td>
            @Html.DisplayFor(m => m[i].Title)
            @Html.HiddenFor(m => m[i].Title)
        </td>
        @* etc ... *@
   <tr>
}

PS: this loop would post all displayed CodeSnips, i.e. the receiving action would have the signature public ActionResult Display(ListOfCodeSnips postData).

Upvotes: 0

Grizzly
Grizzly

Reputation: 5943

Since you said that you have tried with ActionLink and it did not work, here is how it would work.. instead of passing the type that you are looking for as a parameter for the Display action, pass the ID of the record.

So it would look something like this:

Controller Action

[HttpGet]
public ActionResult Display(int id)
{
    var snip = db/* connection string */.TableName.Find(id);
    return View(snip);
}

ActionLink

@Html.ActionLink("Display", "Display", "ControllerName", new { id = item.Id }, null )

// Or if you want a button that acts as a link, and not just a plain link

<input type="button" class="btn" value="Display" onclick="location.href='@Url.Action("Display", "ControllerName", new { id = item.Id })'" />

Let me know if this helps!

Upvotes: 1

Related Questions