2013-03-15 57 views
0

我試圖在我的視圖中創建對象列表,但是在post方法中,進來的參數爲null。創建頁面可以正常加載我想要的所有信息,但是當我單擊「創建」時,我會在我的標題中看到列出的錯誤。我能做什麼錯了?未將對象引用設置爲對象的實例。自定義對象在POST時返回null

員工每天有可用的鏈接。這就是我想實現

型號

public class Availability 
{ 

    [Required] 
    public long Id { get; set; } 

    [Required] 
    [DataType(DataType.Text)] 
    [Display(Name = "Weekday")] 
    public string weekday { get; set; } 

    [DataType(DataType.Time)] 
    [Display(Name = "Start Time")] 
    public DateTime StartTime { get; set; } 

    [DataType(DataType.Time)] 
    [Display(Name = "End Time")] 
    public DateTime EndTime { get; set; } 

    public virtual Employee employee { get; set; } 

} 
} 

自定義類

public class SetAvailability 
{ 
    public long EmpID { get; set; } 
    public String firstName {get; set;} 
    public String lastName { get; set; } 
    public Availability availability {get; set;} 


} 

控制器方法

// GET: /Availability/Create 

    public ActionResult Create(long id) 
    { 
     string[] weekdays ={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 
     //find the employee 
     Employee emp = db.Employees.Find(id); 

     //create a list of setAvailability objects for each day 
     List<SetAvailability> editor = new List<SetAvailability>(); 


     //instantiate each SetAvailability object and populate accordingly for 7 days 
     for (int i = 0; i < 7; i++) 
     { 
      //create a blank SetAvilability 
      var _editor = new SetAvailability(); 

      //create a blank availability 
      _editor.availability = new Availability(); 

      //set the weekday 
      _editor.availability.weekday = weekdays[i].ToString(); 

      //set the employee id, first name and last name 
      _editor.EmpID = emp.Id; 
      _editor.firstName = emp.FirstName; 
      _editor.lastName = emp.LastName; 
      //add the _editor to the editorlist 
      editor.Add(_editor); 
     } 

     return View(editor); 


    } 

    // 
    // POST: /Availability/Create 

    [HttpPost] 
    public ActionResult Create(List<SetAvailability> dto) 
    { 
     //dto object is coming in null! (checked by debugging) 
     List<SetAvailability> temp = new List<SetAvailability>(); 
     temp = dto; 

     if (ModelState.IsValid) 
     { 
      // set the values for each availability object 
      // breaks here! 
      foreach (var item in dto) 
      {      
       // get the employee 
       item.availability.employee = db.Employees.Find(item.EmpID); 

       // weekday should already be set 
       // start and end times should come in from the create view 

       db.Availability.Add(item.availability); 
      } 
      db.SaveChanges(); 
      return RedirectToAction("Index","employee"); 
     } 

     return View(temp); 
    } 

查看

@model List<VolumeV2.Models.DTOs.SetAvailability> 

@{ 
ViewBag.Title = "Create"; 

} 

<h2>Create</h2> 

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

<fieldset> 
    <legend>Availability</legend> 

    <table> 
     <tr> 
     @foreach (var item in Model)     
      {    
        @Html.HiddenFor(model => item.EmpID) 
        @Html.HiddenFor(model => item.firstName) 
        @Html.HiddenFor(model => item.lastName) 
      <td> 
       @Html.LabelFor(model => item.availability.weekday) 
      </td>     
      <td> 
       @Html.LabelFor(model => item.availability.StartTime)     
      </td> 
      <td> 
       @Html.LabelFor(model => item.availability.EndTime)     
      </td>     
      break; 
     } 
     </tr> 
     @foreach (var item in Model){ 
        @Html.HiddenFor(model => item.EmpID) 
        @Html.HiddenFor(model => item.firstName) 
        @Html.HiddenFor(model => item.lastName) 
      <tr> 
       <td> 
       @Html.EditorFor(modelitem => item.availability.weekday) 
       @Html.ValidationMessageFor(modelitem => item.availability.weekday) 
       </td> 

       <td>       
       @Html.EditorFor(modelitem => item.availability.StartTime) 
       @Html.ValidationMessageFor(modelitem => item.availability.StartTime) 
       </td> 

       <td>       
       @Html.EditorFor(modelitem => item.availability.EndTime) 
       @Html.ValidationMessageFor(modelitem => item.availability.EndTime) 
       </td> 
      </tr> 
     } 
    </table> 
    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 
} 

<div> 
@Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
@Scripts.Render("~/bundles/jqueryval") 
} 

enter image description here

+0

嘗試編輯模板。 – ssilas777 2013-03-15 06:36:03

+0

你會碰巧知道一個很好的基本MVC4教程嗎?我很難找到一個好的源碼 – Fpanico 2013-03-15 06:53:25

回答

0

試試這個

要在POST獲取對象的集合方法就需要修改Html.BeginForm, 添加以下Helper類在你的將返回你的應用程序列表的對象。 (例如輔助類DemoApplication /模型的位置/)

public static class HtmlPrefixScopeExtensions 
    { 
     private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_"; 

     public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName) 
     { 
      var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName); 
      string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString(); 

      // autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync. 
      html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex))); 

      return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex)); 
     } 

     public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix) 
     { 
      return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix); 
     } 

     private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName) 
     { 
      // We need to use the same sequence of IDs following a server-side validation failure, 
      // otherwise the framework won't render the validation error messages next to each item. 
      string key = idsToReuseKey + collectionName; 
      var queue = (Queue<string>)httpContext.Items[key]; 
      if (queue == null) { 
       httpContext.Items[key] = queue = new Queue<string>(); 
       var previouslyUsedIds = httpContext.Request[collectionName + ".index"]; 
       if (!string.IsNullOrEmpty(previouslyUsedIds)) 
        foreach (string previouslyUsedId in previouslyUsedIds.Split(',')) 
         queue.Enqueue(previouslyUsedId); 
      } 
      return queue; 
     } 

     private class HtmlFieldPrefixScope : IDisposable 
     { 
      private readonly TemplateInfo templateInfo; 
      private readonly string previousHtmlFieldPrefix; 

      public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix) 
      { 
       this.templateInfo = templateInfo; 

       previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix; 
       templateInfo.HtmlFieldPrefix = htmlFieldPrefix; 
      } 

      public void Dispose() 
      { 
       templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix; 
      } 
     } 
    } 

後改性查看

@model List<VolumeV2.Models.DTOs.SetAvailability> 



    @{ 
    ViewBag.Title = "Create"; 

    } 

    <h2>Create</h2> 


@Html.ValidationSummary(true) 

    @using(Html.BeginForm()) 
    { 

     <fieldset> 
      <legend>Availability</legend> 

      <table> 

       @foreach (var item in Model)     
        {  

        @Html.Partial("_partialView",item) 
       } 


      </table> 
      <p> 
       <input type="submit" value="Create" /> 
      </p> 
     </fieldset> 
     } 

     <div> 
     @Html.ActionLink("Back to List", "Index") 
     </div> 

     @section Scripts { 
     @Scripts.Render("~/bundles/jqueryval") 
     } 

創建的局部視圖 _partailView.cshtml

@model VolumeV2.Models.DTOs.SetAvailability 
    @using DemoApplication.Models // Added Helper class reference 
    <tr> 
    @using (Html.BeginCollectionItem("dto")) { 

           @Html.HiddenFor(model => model.EmpID) 
           @Html.HiddenFor(model => model.firstName) 
           @Html.HiddenFor(model => model.lastName) 
         <td> 
          @Html.LabelFor(model => model.availability.weekday) 
         </td>     
         <td> 
          @Html.LabelFor(model => model.availability.StartTime)     
         </td> 
         <td> 
          @Html.LabelFor(model => model.availability.EndTime)     
         </td>     
         break; 

         } 
      </tr> 

注意:必須在POST方法中保留Html.BeginCollectionItem(「dto」)和參數名稱的相同名稱,否則您將不會在POST方法中獲得值,並且還會添加助手類參考在您的看法。

+0

我已經在我的項目中添加了html helper類,並將它包含在視圖中,並且現在更改了beginCollectionItem廣告我的創建按鈕不會執行任何操作 – Fpanico 2013-03-15 06:48:00

+0

@Fpanico我已經完成了一些操作視圖變化請檢查它。 – Shivkumar 2013-03-15 07:26:41

0

要快速解決這個問題,您可以使用「for」循環在列表項上使用索引,因爲這將呈現控件的名稱以適應MVC模型綁定的命名約定。例如,[0] .availability.weekday,[1] .availability.weekday等等,表示具有相應索引的項目數組,以便能夠在模型綁定時構建項目列表。

@model List<MvcApplication5.Models.SetAvailability> 

@using (Html.BeginForm("Create","Employee")) { 
@Html.ValidationSummary(true) 

<fieldset> 
    <legend>Availability</legend> 

    <table> 
     <tr> 
     @for (int i = 0; i < Model.Count; i++) 
     { 
      @Html.HiddenFor(model => Model[i].EmpID) 
        @Html.HiddenFor(model => Model[i].firstName) 
        @Html.HiddenFor(model => Model[i].lastName) 
      <td> 
       @Html.LabelFor(model => Model[i].availability.weekday) 
      </td>     
      <td> 
       @Html.LabelFor(model => Model[i].availability.StartTime)     
      </td> 
      <td> 
       @Html.LabelFor(model => Model[i].availability.EndTime)     
      </td>     
      break; 
     } 
     </tr> 
     @for (int i = 0; i < Model.Count; i++) 
     { 
      @Html.HiddenFor(model => Model[i].EmpID) 
        @Html.HiddenFor(model => Model[i].firstName) 
        @Html.HiddenFor(model => Model[i].lastName) 
      <tr> 
       <td> 
       @Html.EditorFor(modelitem => Model[i].availability.weekday) 
       @Html.ValidationMessageFor(modelitem => Model[i].availability.weekday) 
       </td> 

       <td>       
       @Html.EditorFor(modelitem => Model[i].availability.StartTime) 
       @Html.ValidationMessageFor(modelitem => Model[i].availability.StartTime) 
       </td> 

       <td>       
       @Html.EditorFor(modelitem => Model[i].availability.EndTime) 
       @Html.ValidationMessageFor(modelitem => Model[i].availability.EndTime) 
       </td> 
      </tr> 
     } 
    </table> 
    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 
} 

現在,您應該在POST之後的列表中看到七個項目。希望這對你有所幫助。

相關問題