Reputation: 1181
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
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
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);
}
@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