2016-08-30 112 views
0

我有一个从数据库返回结果的小型serach框。这工作正常。结果显示在“列表”页面中并正确显示。但是,我需要将选定的对象传递给我的控制器。当我调试它时,我得到NULL值,并且有一个空的结果页面。 这里是模型:MVC从列表视图页面传递所选对象

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 
} 

这里是控制器方法(其中不执行任何大气压):

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

以下是我有一个图。再次,它的职位只NULLS为对象的值:

@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> 

等等,总之,我想要做的就是从视图下所选择的模型项目,并将其传递到我控制器显示方法,但我说,我所得到的都是空值。 我环顾四周,我发现的所有例子都是如何传递对象列表。我试图与这些人一起瞎搞,但什么也没得到。

谢谢你的时间。

+0

如果你没有做任何计算或试图保存/改变数据库的数据库,而只是想显示*他们..为什么使用'HttpPost'请求而不是'HttpGet'请求? –

+0

这种方法有没有优势,如果是的话,我该怎么做?我尝试了一个ActionLink,但仍然无法传递对象 – rigamonk

+0

rigamonk

回答

1

既然你说你已经尝试过使用ActionLink并且它没有工作,这里是它将如何工作..而不是通过你正在寻找的类型作为Display动作的参数,传递ID记录。

因此,这将是这个样子:

控制器动作

[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 })'" /> 

让我知道,如果这有助于!

+0

虽然我已经这样做了,但我不想再打第二个电话到数据库(尽管它相当便宜) – rigamonk

+0

@rigamonk好吧,但这解释了为什么你点击按钮时得到空值的原因..你的代码不知道你想要*显示哪个记录* ..你只是在调用一个空的CodeSnip模型...你需要使用'ID',因为它对每个记录都是唯一的 –

0

有两个问题与您的代码:

1)你不渲染,你所选择的值发送回控制器的任何<input>元素。除了Html.DisplayFor之外,还使用Html.HiddenForHtml.EditorFor

2)为了使MVC Modelbinder能够绑定您的列表,请使用for循环代替foreach

又见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:这个循环会后都显示CodeSnips,即接收行动将有签名public ActionResult Display(ListOfCodeSnips postData)