2012-02-20 3 views
1

У меня есть следующий контроллер и просмотр. Он правильно перечисляет значения, используя GET. Когда я нажимаю на кнопку, она вызывает POST. Однако значение, полученное в контроллере, равно NULL. Как мы это исправим?ASP.NET MVC3: View POSTed значение модели NULL

подсвеченный код

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

GET Изображение

enter image description here

КОД

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; } 
} 

CONTROLLER

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); 
    } 


    } 
} 

VIEW

@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 Wire Формат для модели Связующие для Массивы, списки, Коллекции, словари

  5. модели привязки к списку


+0

Displayfor является вероятно, генерируя ProgramName (в имени attr) для полного списка, который не может быть bo и обратно к модели. проверьте имена в html, я думаю, они должны быть ProgramName [0], ProgramName [1] и т. д. –

+0

Поскольку я новичок в MVC, я не совсем понял вашу точку зрения. Не могли бы вы предоставить демо-версию кода? Кроме того, I число программ является динамическим (из базы данных) в реальном сценарии. – Lijo

+1

, чтобы проверить, какие значения на самом деле выставляются, примите свой параметр FormCollection в своем посту. –

ответ

4

Замените петлю 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> 
} 

, а затем определить шаблон редактора, который будет автоматически отображаться для каждого элемента в m Одел (~/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, чтобы лучше понять формат провода, который ожидается для коллекций.

+0

@ Lijo, это скорее всего из-за того, что вы допустили ошибку в названии вашего шаблона редактора. Убедитесь, что он находится в '~/Views/Shared/EditorTemplates /' и что он называется 'Program.cshtml'. Если он не отображается, это означает, что вы не разместили шаблон в нужном месте. Двойная проверка еще раз. –

+1

@ Lijo, я допустил ошибку в своем коде. Вы должны использовать '@ Html.EditorFor' вместо' @ Html.DisplayFor' в шаблоне. Я обновил свой ответ, чтобы исправить это. DisplayFor просто создает ярлык. Вам нужно использовать поле ввода, если вы хотите сохранить значение при отправке на контроллер. –

+0

@ Lijo, у вас есть 2 входа для него. Один '@ Html.EditorFor (x => x.RatingID)' и один '@ Html.DropDownListFor'. Вы должны решить, какой из них использовать для привязки этого значения. Затем удалите другой. –

0

Спасибо Дарин. Я принял его ответ. Полное решение опубликовано в интересах других, читающих это.

Примечание: EditorTemplate помог избежать цикла foreach и помог в правильном привязке объектов.

Примечание: The 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); 
    } 


} 
} 

View (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> 
1

этот код работать для меня:

  1. Контроллер: [HttpPost] общественного 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> 

}

+0

Спасибо. Что вы думаете о том, что я написал выше? – Lijo

Смежные вопросы