2014-01-11 65 views
3

我要發佈項目列表,從Razor視圖控制器,但我正在逐漸對象的列表爲空 我的班級結構法是MVC如何傳遞對象的列表,列表項POST操作方法

型號:

List<Subjects> modelItem 

class Subjects 
{ 
    int SubId{get;set;} 
    string Name{get;set;} 
    List<Students> StudentEntires{get;set;} 
} 

class StudentEntires 
{ 
    int StudId{get;set;} 
    string Name{get;set;} 
    int Mark{get;set;} 
} 

該模型本身是一個項目列表,每個項目也包含子項目列表。例如型號爲主題的列表,每個主題包含的學生名單,我想輸入標記爲每個學生

我的看法是一樣

@model IList<Subjects> 
@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
@using (Html.BeginForm()) 
{  
    @Html.ValidationSummary(true) 
    if (Model.Count > 0) 
    { 
     @for (int item = 0; item < Model.Count(); item++) 
     { 
      <b>@Model[item].Name</b><br /> 
      @foreach (StudentEntires markItem in Model[item].StudentEntires) 
      { 
       @Html.TextBoxFor(modelItem => markItem.Mark) 
      } 
     } 
     <p style="text-align:center"> 
      <input type="submit" class="btn btn-primary" value="Update" /> 
     </p> 
    } 
} 

並在控制器

[HttpPost] 
    public ActionResult OptionalMarks(int Id,ICollection<Subjects> model) 
    { 
     //BUt my model is null. Any idea about this? 
    } 
+0

你如何將模型發送到'OptionalMarks' GET方法的視圖? –

+0

是的。首先找到一個科目列表,併爲每個科目,得到一個學生名單 –

回答

1

將操作方法​​簽名更改爲

public ActionResult OptionalMarks(ICollection<Subjects> model)

由於在您的HTML中,它看起來不像在那裏有任何名爲Id的東西。但這不是你的主要問題。

接下來要做的是與福爾環

@for(int idx = 0; idx < Model[item].StudentEntires.Count();idx++) 
{ 
    @Html.TextBoxFor(_ => Model[item].StudentEntries[idx]) 
} 

可能跟隨由於使用foreach循環爲StudentEntries,模型綁定是有問題的拼湊一切融合在一起,從而返回NULL。

編輯:

下面是一個例子:

控制器

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var viewModel = new IndexViewModel(); 

     var subjects = new List<Subject>(); 
     var subject1 = new Subject(); 

     subject1.Name = "History"; 
     subject1.StudentEntires.Add(new Student { Mark = 50 }); 
     subjects.Add(subject1); 

     viewModel.Subjects = subjects; 

     return View(viewModel); 
    } 

    [HttpPost] 
    public ActionResult Index(IndexViewModel viewModel) 
    { 
     return new EmptyResult(); 
    } 
} 

查看

@model SOWorkbench.Controllers.IndexViewModel 

@{ 
    ViewBag.Title = "Home Page"; 
} 

@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 
    if (Model.Subjects.Any()) 
    { 
     int subjectsCount = Model.Subjects.Count(); 
     for (int item = 0; item < subjectsCount; item++) 
     { 
      <b>@Model.Subjects[item].Name</b><br />    
      int studentEntriesCount = Model.Subjects[item].StudentEntires.Count(); 

      for(int idx = 0;idx < studentEntriesCount;idx++) 
      { 
       @Html.TextBoxFor(_ => Model.Subjects[item].StudentEntires[idx].Mark); 
      } 
     } 
     <p style="text-align:center"> 
      <input type="submit" class="btn btn-primary" value="Update" /> 
     </p> 
    } 
} 

當您張貼的形式,你應該看到DA ta回到viewModel的對象中。

+0

像這樣conveerted代碼,但仍然獲得子列表爲空(但只有StudentEntries列表)。主模型列表不是空的,即SubId,Name不爲空,但StudentEntires列表爲空 –

20

您發現這很困難,因爲您沒有充分利用MVC框架的功能,所以請允許我提供一個工作示例。

首先亮相,讓我們創建一個視圖模型來封裝視圖的數據要求:

public class SubjectGradesViewModel 
{ 
    public SubjectGradesViewModel() 
    { 
     Subjects = new List<Subject>(); 
    } 

    public List<Subject> Subjects { get; set; } 
} 

接下來,創建一個類來表示你的主題模式:

public class Subject 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public List<Student> StudentEntries { get; set; } 
} 

最後一個類來表示一個學生:

public class Student 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int Grade { get; set; } 
} 

在這一點上,你有所有你需要的類代表你的數據。現在,讓我們創建兩個控制器動作,包括一些樣本數據,所以你可以看到這是如何工作:

public ActionResult Index() 
{ 
    var model = new SubjectGradesViewModel(); 

    // This sample data would normally be fetched 
    // from your database 
    var compsci = new Subject 
    { 
     Id = 1, 
     Name = "Computer Science", 
     StudentEntries = new List<Student>() 
     { 
      new Student { Id = 1, Name = "CompSci 1" }, 
      new Student { Id = 2, Name = "CompSci 2" }, 
     } 
    }; 

    var maths = new Subject 
    { 
     Id = 2, 
     Name = "Mathematics", 
     StudentEntries = new List<Student>() 
     { 
      new Student { Id = 3, Name = "Maths 1" }, 
      new Student { Id = 4, Name = "Maths 2" }, 
     } 
    }; 

    model.Subjects.Add(compsci); 
    model.Subjects.Add(maths); 

    return View(model); 
} 

[HttpPost] 
public ActionResult Index(SubjectGradesViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     return RedirectToAction("Success"); 
    } 

    // There were validation errors 
    // so redisplay the form 
    return View(model); 
} 

現在是時候建造的意見,當涉及到數據發送回控制器,這部分就顯得尤爲重要。首先登場的是Index觀點:

@model SubjectGradesViewModel 

@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 

    @Html.EditorFor(m => m.Subjects) <br /> 
    <input type="submit" /> 
} 

你我只是使用Html.EditorFor,同時傳遞Subjects作爲參數注意。我這樣做的原因是因爲我們要創建一個EditorTemplate來代表Subject。稍後我會解釋更多。現在,只知道EditorTemplatesDisplayTemplates是MVC中的特殊文件夾名稱,因此它們的名稱和位置很重要。

我們實際上要創建兩個模板:一個用於Subject,另一個用於Student。要做到這一點,請按照下列步驟操作:

  1. 創建視圖的當前文件夾內的文件夾EditorTemplates(例如,如果你的觀點是Home\Index.cshtml,創建文件夾Home\EditorTemplates)。
  2. 在該目錄中創建一個名稱與您的模型匹配的強類型視圖(即在這種情況下,您將創建兩個視圖,分別稱爲Subject.cshtmlStudent.cshtml(同樣,命名很重要))。

Subject.cshtml應該是這樣的:

@model Subject 

<b>@Model.Name</b><br /> 

@Html.HiddenFor(m => m.Id) 
@Html.HiddenFor(m => m.Name) 
@Html.EditorFor(m => m.StudentEntries) 

Student.cshtml應該是這樣的:

@model Student 

@Html.HiddenFor(m => m.Id) 
@Html.HiddenFor(m => m.Name) 
@Html.DisplayFor(m => m.Name): @Html.EditorFor(m => m.Grade) 
<br /> 

就是這樣。如果您現在構建並運行此應用程序,請在POST索引操作中添加一個斷點,您會看到模型已正確填充。

那麼,什麼是EditorTemplates,和他們的對應,DisplayTemplates?它們允許您創建視圖的可重用部分,使您可以更多地組織您的視圖。

關於他們的好處是模板幫手,即Html.EditorForHtml.DisplayFor,足夠聰明,知道他們何時處理集合的模板。這意味着您不必循環播放項目,每次都需要手動調用模板。您也不必執行任何nullCount()檢查,因爲幫助人員將爲您處理所有問題。你留下的觀點是乾淨的,沒有邏輯。

EditorTemplates當您希望將收集發佈到控制器操作時,也會生成適當的名稱。這使得模型綁定到一個列表,比自己生成這些名稱要簡單得多。有時你仍然需要這樣做,但這不是其中之一。

相關問題