【问题标题】:ASP.NET MVC3: View POSTed model value is NULLASP.NET MVC3:查看 POSTed 模型值为 NULL
【发布时间】:2012-03-10 13:13:55
【问题描述】:

我有以下控制器和视图。它使用 GET 正确列出了值。当我单击按钮时,它会导致 POST。但是,控制器中接收到的值为 NULL。我们如何纠正它?

高亮代码

    [HttpPost]
    public ActionResult CastVote(IEnumerable<Program> theProgramList)

获取图片

代码

 public enum RatingEnum { Poor = 0, Neutral, Good, Excellent };

public class Program
{
    public int ProgramID { get; set; }
    public string ProgramName { get; set; }
    public RatingEnum RatingID { get; set; }
    public string ProgramCategory { get; set; }
}

控制器

namespace MyProgramRatingApp.Controllers
{
public class ProgramController : Controller
{




    List<Program> programList = new List<Program>()
                          {
                            new Program
                            {
                                ProgramID = 1,ProgramName = "Program1",
                                ProgramCategory = "A"
                            },
                            new Program
                            {
                                ProgramID = 2,ProgramName = "Program2",
                                ProgramCategory = "B"
                            },
                            new Program
                            {
                                ProgramID = 3,ProgramName = "Program3",
                                ProgramCategory = "A"
                            }

                          };




    // GET: /Program/
    public ActionResult CastVote()
    {
        ViewBag.RatingEnum = GetRstingSelectList();
        return View(programList);
    }


    // POST: /StoreManager/Create
    [HttpPost]
    public ActionResult CastVote(IEnumerable<Program> theProgramList)
    {
        if (ModelState.IsValid)
        {
            //Save the book in DB first and then redirectToAction.


            return RedirectToAction("CastVote");
        }

        return View(theProgramList);
    }


    public static SelectList GetRstingSelectList()
    {
        Array values = Enum.GetValues(typeof(RatingEnum));
        List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>(values.Length);

        foreach (var i in values)
        {
            items.Add(new System.Web.UI.WebControls.ListItem
                                    {
                                        Text = Enum.GetName(typeof(RatingEnum), i),
                                        Value = ((int)i).ToString()
                                    }
                       );
        }

        return new SelectList(items);
    }


    }
}

查看

@model IEnumerable<MyProgramRatingApp.Program>

@{
ViewBag.Title = "CastVote";
}

<h2>CastVote</h2>

@using (Html.BeginForm())
{
<table>
    <tr>
        <th style="border:1px solid Teal; background-color:Gray">
            ProgramName
        </th>
        <th style="border:1px solid Teal; background-color:Gray">
            RatingID
        </th>
        <th style="border:1px solid Teal; background-color:Gray">
            ProgramCategory
        </th>
        <th style="border:1px solid Teal; background-color:Gray"></th>
    </tr>

@foreach (var item in Model)
{
    <tr>
        <td style="border:1px solid Teal">
            @Html.DisplayFor(modelItem => item.ProgramName)
        </td>
        <td style="border:1px solid Teal">
            @Html.DisplayFor(modelItem => item.RatingID)
        </td>
        <td style="border:1px solid Teal">
            @Html.DisplayFor(modelItem => item.ProgramCategory)
        </td>
        <td style="border:1px solid Teal">
            @Html.DropDownListFor(model => item.RatingID, (SelectList)ViewBag.RatingEnum, String.Empty)
        </td>

    </tr>
}

</table>

<p>
    <input type="submit" value="Cast Vote" />
</p>

}

阅读:

  1. dropdownlist set selected value in MVC3 Razor

  2. ASP.NET MVC 3 - Partial vs Display Template vs Editor Template

  3. IEnumerable property with MVC3 EditorTemplate

  4. 用于模型绑定到数组、列表、集合、字典的 ASP.NET 有线格式

  5. 模型绑定到列表


【问题讨论】:

  • DisplayFor 可能正在为无法绑定回模型的完整列表生成 ProgramName(在名称 attr 中)。检查 html 中的名称,我认为它们需要是 ProgramName[0]、ProgramName[1] 等。
  • 由于我是MVC的新手,我不太明白你的意思。你能提供一个代码演示吗?此外,我的程序数量在实际场景中是动态的(来自数据库)。
  • 检查实际发布的值在您的发布操作中接受 FormCollection 参数。
  • 我使用FormCollection时,allKeys中只有一个字符串。它是“item.RatingID”

标签: asp.net-mvc asp.net-mvc-3


【解决方案1】:

将视图中的 foreach 循环替换为对编辑器模板的调用:

@model IEnumerable<MyProgramRatingApp.Program>

@{
    ViewBag.Title = "CastVote";
}

<h2>CastVote</h2>

@using (Html.BeginForm())
{
    <table>
        <tr>
            <th style="border:1px solid Teal; background-color:Gray">
                ProgramName
            </th>
            <th style="border:1px solid Teal; background-color:Gray">
                RatingID
            </th>
            <th style="border:1px solid Teal; background-color:Gray">
                ProgramCategory
            </th>
            <th style="border:1px solid Teal; background-color:Gray"></th>
        </tr>

        @Html.EditorForModel()

    </table>

    <p>
        <input type="submit" value="Cast Vote" />
    </p>
}

然后定义将为模型中的每个元素自动呈现的编辑器模板(~/Views/Shared/EditorTemplates/Program.cshtml):

@model MyProgramRatingApp.Program
<tr>
    <td style="border:1px solid Teal">
        @Html.EditorFor(x => x.ProgramName)
    </td>
    <td style="border:1px solid Teal">
        @Html.EditorFor(x => x.RatingID)
    </td>
    <td style="border:1px solid Teal">
        @Html.EditorFor(x => x.ProgramCategory)
    </td>
    <td style="border:1px solid Teal">
        @Html.DropDownListFor(
             x => x.RatingID, 
             (SelectList)ViewBag.RatingEnum, 
             String.Empty
        )
    </td>
</tr>

请注意,我在编辑器模板中使用了@Html.EditorFor 而不是@Html.DisplayFor 来生成输入字段。如果您不这样做,您将不会在控制器中获得任何值,因为您的表单不包含任何输入元素。如果您不想显示输入字段,可以使用隐藏输入:

@model MyProgramRatingApp.Program
<tr>
    <td style="border:1px solid Teal">
        @Html.DisplayFor(x => x.ProgramName)
        @Html.HiddenFor(x => x.ProgramName)
    </td>
    <td style="border:1px solid Teal">
        @Html.DisplayFor(x => x.RatingID)
        @Html.HiddenFor(x => x.RatingID)
    </td>
    <td style="border:1px solid Teal">
        @Html.DisplayFor(x => x.ProgramCategory)
        @Html.HiddenFor(x => x.ProgramCategory)
    </td>
    <td style="border:1px solid Teal">
        @Html.DropDownListFor(
             x => x.RatingID, 
             (SelectList)ViewBag.RatingEnum, 
             String.Empty
        )
    </td>
</tr>

编辑器模板将为输入字段生成正确的名称,以便模型绑定器正确绑定值。

您还可以查看following article,以更好地了解集合所需的电汇格式。

【讨论】:

  • @Lijo,这很可能是因为您在编辑器模板的命名中犯了一些错误。确保它位于~/Views/Shared/EditorTemplates/ 并且它被称为Program.cshtml。如果未显示,则表示您没有将模板放置在正确的位置。再次仔细检查。
  • @Lijo,我的代码出错了。您应该在模板中使用@Html.EditorFor 而不是@Html.DisplayFor。我已经更新了我的答案来解决这个问题。 DisplayFor 只生成一个标签。如果要在发布到控制器时保留值,则需要使用输入字段。
  • @Lijo,你有 2 个输入。一个@Html.EditorFor(x =&gt; x.RatingID) 和一个@Html.DropDownListFor。您必须决定使用两者中的哪一个来绑定此值。然后删除另一个。
  • @Lijo,您似乎正在使用枚举类型将下拉列表绑定到:ViewBag.RatingEnum。这显然不适用于您的x =&gt; x.RatingID,因为您的RatingID 属性是一个整数。也许您可以尝试将其声明为public RatingEnum ProgramID { get; set; }
  • @Lijo,使用Html.DisplayFor(x =&gt; x.ProgramName) 并放置一个额外的隐藏字段以传递值Html.HiddenFor(x =&gt; x.ProgramName)。我已经在回答中解释了这一点,甚至举了一个例子。
【解决方案2】:

这段代码对我有用:

  1. 控制器: [HttpPost] public ActionResult CastVote(Ilist theProgramList)

2 视图:

@model IList<Program>
@using (Html.BeginForm())
{
<table>
    <tr>
        <th style="border:1px solid Teal; background-color:Gray">
            ProgramName
        </th>
        <th style="border:1px solid Teal; background-color:Gray">
            ProgramCategory
        </th>
        <th style="border:1px solid Teal; background-color:Gray">  </th>
    </tr>

@for(var i=0,j=mode.Count;i<j;i++)
{
  <tr>
     <td>@model[i].ProgrameName</td>
     <td><input type="text" name="RaingID[@i]" value="@model[i].RatingID"</td>


      <td>
        @Html.DropDownListFor(x => x.Rating, 
                      (SelectList)ViewBag.RatingEnum, new {@name="ProgramCategory[i] "})
     </td>
  </tr>
}
<p>
    <input type="submit" value="Cast Vote" />
</p>

</table>

}

【讨论】:

  • 谢谢。您如何看待我在上面发布的答案?
【解决方案3】:

感谢达林。我接受了他的回答。发布完整的解决方案是为了让其他阅读本文的人受益。

注意:EditorTemplate 有助于避免 foreach 循环并有助于正确的对象绑定。

注意:EditorTemplate 应放置在适当的文件夹中,文件名应基于约定。

//型号

namespace MyProgramRatingApp
{
public enum RatingEnum { Poor = 0, Neutral, Good, Excellent };

public class Program
{
    public int ProgramID { get; set; }
    public string ProgramName { get; set; }
    public RatingEnum Rating { get; set; }
    public string ProgramCategory { get; set; }
}
}

//控制器

using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace MyProgramRatingApp.Controllers
{

public class ProgramController : Controller
{


    List<Program> programList = new List<Program>()
                          {
                            new Program
                            {
                                ProgramID = 1,ProgramName = "Program1",
                                ProgramCategory = "A"
                            },
                            new Program
                            {
                                ProgramID = 2,ProgramName = "Program2",
                                ProgramCategory = "B"
                            },
                            new Program
                            {
                                ProgramID = 3,ProgramName = "Program3",
                                ProgramCategory = "A"
                            }

                          };




    // GET: /Program/
    public ActionResult CastVote()
    {
        ViewBag.RatingEnum = GetRstingSelectList();
        return View(programList);
    }


    // POST: /StoreManager/Create
    [HttpPost]
    public ActionResult CastVote(IEnumerable<Program> theProgramList)
    {
        if (ModelState.IsValid)
        {
            //Save the book in DB first and then redirectToAction.
            return RedirectToAction("CastVote");
        }

        return View(theProgramList);
    }


    public static SelectList GetRstingSelectList()
    {
        Array values = Enum.GetValues(typeof(RatingEnum));
        List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>(values.Length);

        foreach (var i in values)
        {
            items.Add(new System.Web.UI.WebControls.ListItem
                                    {
                                        Text = Enum.GetName(typeof(RatingEnum), i),
                                        Value = ((int)i).ToString()
                                    }
                       );
        }

        return new SelectList(items);
    }


 }
}

查看(CastVote.cshtml)

@model IEnumerable<MyProgramRatingApp.Program>

@{
ViewBag.Title = "CastVote";
}

<h2>CastVote</h2>

@using (Html.BeginForm())
{
<table>
    <tr>
        <th style="border:1px solid Teal; background-color:Gray">
            ProgramName
        </th>
        <th style="border:1px solid Teal; background-color:Gray">
            ProgramCategory
        </th>
        <th style="border:1px solid Teal; background-color:Gray">  </th>
    </tr>

    @Html.EditorForModel()

</table>

<p>
    <input type="submit" value="Cast Vote" />
</p>
}

EditorTemplate(Program.cshtml)

@model MyProgramRatingApp.Program
<tr>
<td style="border:1px solid Teal">
    @Html.DisplayFor(x => x.ProgramName)
    @Html.HiddenFor(x => x.ProgramName)
</td>
<td style="border:1px solid Teal">
    @Html.EditorFor(x => x.ProgramCategory)
</td>
<td style="border:1px solid Teal">
    @Html.DropDownListFor(x => x.Rating, (SelectList)ViewBag.RatingEnum, String.Empty)
</td>
<td>
    @Html.HiddenFor(x => x.ProgramID)
</td>

</tr>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多