2010-09-02 56 views
2

设置我有一个模型对象调用问题:ASP.NET MVC表单值不上张贴

[Table(Name = "Problems")] 
public class Problem 
{ 
    [HiddenInput(DisplayValue = false)] 
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
    public int ProblemId { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TablePersonStudentName")] 
    [Column] public int StudentId { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableCommunicationTypesName")] 
    [Column] public int CommunicationTypeId { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemTypeName")] 
    [Column] public int ProblemTypeId { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableMitigatingCircumstanceLevelName")] 
    [Column] public int MitigatingCircumstanceLevelId { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemDate")] 
    [Column] public DateTime? DateTime { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemOutline")] 
    [Column] public string Outline { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemFile")] 
    [Column] public byte[] MitigatingCircumstanceFile { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemAbsentFrom")] 
    [Column] public DateTime? AbsentFrom { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemAbsentUntil")] 
    [Column] public DateTime? AbsentUntil { get; set; } 

    [Display(ResourceType = typeof(Resources.Resources), Name = "TableProblemRequestedFollowUp")] 
    [Column] public DateTime? RequestedFollowUp { get; set; } 

    public CommunicationType CommunicationType { get; set; } 

    public MitigatingCircumstanceLevel MitigatingCircumstanceLevel { get; set; } 

    public ProblemType ProblemCategory { get; set; } 

    public ICollection<ProblemCommunication> ProblemCommunications { get; set; } 

    public ICollection<AssessmentExtension> AssessmentExtensions { get; set; } 

    public ICollection<User> Users { get; set; } 

} 

由于这种模式包含了许多从我使用dropdownlists其他数据库表在我看来对象的使用视图模型:

public class ProblemViewModel 
{ 
    public Problem Problem { get; set; } 
    public SelectList Students { get; set; } 
    public SelectList CommunicationType { get; set; } 
    public SelectList MitigatingCircumstanceLevel { get; set; } 
    public SelectList ProblemType { get; set; } 
    public MultiSelectList ProblemUsers { get; set; } 

    public ProblemViewModel(Problem problem, ISqlStudentRepository sqlStudentRepository, 
     ISqlCommunicationTypeRepository sqlCommunicationTypeRepository, ISqlMitigatingCircumstanceLevelRepository sqlMitigatingCircumstanceRepository, 
     ISqlProblemTypeRepository sqlProblemTypeRepository, ISqlUserRepository sqlUserRepository, 
     string username) 
    { 
     this.Problem = problem; 
     this.Students = new SelectList(sqlStudentRepository.Students.ToList(), "StudentId", "FirstName"); 
     this.CommunicationType = new SelectList(sqlCommunicationTypeRepository.CommunicationTypes.ToList(), "CommunicationTypeId", "Name"); 
     this.MitigatingCircumstanceLevel = new SelectList(sqlMitigatingCircumstanceRepository.MitigatingCircumstanceLevels.ToList(), "MitigatingCircumstanceLevelId", "Name"); 
     this.ProblemType = new SelectList(sqlProblemTypeRepository.ProblemTypes.ToList(), "ProblemTypeId", "TypeName"); 
     this.ProblemUsers = new MultiSelectList(sqlUserRepository.Users.Where(s => s.UserName != username).ToList(), "UserId", "UserName"); 
    } 
} 

这是在导航生成对问题/创建控制器的方法:

public ViewResult Create() 
    { 
     string username = User.Identity.Name; 

     return View("Edit", new ProblemViewModel(new Problem(), sqlStudentRepository, 
      sqlCommunicationTypeRepository, sqlMitigatingCircumstanceRepository, 
      sqlProblemTypeRepository, sqlUserRepository, username)); 
    } 

这里是ascx的看法:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BournemouthUniversity.WebUI.Models.ProblemViewModel>" %> 
 <div class="editor-field"> 
      <%: Html.HiddenFor(model => model.Problem.ProblemId)%> 
      <%: Html.ValidationMessageFor(model => model.Problem.ProblemId)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.StudentId) %> 
     </div> 
     <div class="editor-field"> 
      <%: Html.DropDownListFor(model => model.Problem.StudentId, Model.Students)%> 
      <%: Html.ValidationMessageFor(model => model.Problem.StudentId)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.CommunicationTypeId)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.DropDownListFor(model => model.Problem.CommunicationTypeId, Model.CommunicationType)%> 
      <%: Html.ValidationMessageFor(model => model.Problem.CommunicationTypeId)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.ProblemTypeId)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.DropDownListFor(model => model.Problem.ProblemTypeId, Model.ProblemType)%> 
      <%: Html.ValidationMessageFor(model => model.Problem.ProblemTypeId)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.MitigatingCircumstanceLevelId)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.DropDownListFor(model => model.Problem.MitigatingCircumstanceLevelId, Model.MitigatingCircumstanceLevel)%> 
      <%: Html.ValidationMessageFor(model => model.Problem.MitigatingCircumstanceLevelId)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.DateTime)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.TextBoxFor(model => model.Problem.DateTime, new { @class = "datePicker" })%> 
      <%: Html.ValidationMessageFor(model => model.Problem.DateTime)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.Outline)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.TextAreaFor(model => model.Problem.Outline, 6, 70, new { maxlength = 255 })%> 
      <%: Html.ValidationMessageFor(model => model.Problem.Outline)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.AbsentFrom)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.TextBoxFor(model => model.Problem.AbsentFrom, new { @class = "datePicker" })%> 
      <%: Html.ValidationMessageFor(model => model.Problem.AbsentFrom)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.AbsentUntil)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.TextBoxFor(model => model.Problem.AbsentUntil, new { @class = "datePicker" })%> 
      <%: Html.ValidationMessageFor(model => model.Problem.AbsentUntil)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.RequestedFollowUp)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.TextBoxFor(model => model.Problem.RequestedFollowUp, new { @class = "dateTimePicker" })%> 
      <%: Html.ValidationMessageFor(model => model.Problem.RequestedFollowUp)%> 
     </div> 

     <div class="editor-label"> 
      <%: Html.LabelFor(model => model.Problem.Users)%> 
     </div> 
     <div class="editor-field"> 
      <%: Html.ListBoxFor(model => model.Problem.Users, Model.ProblemUsers, new { @class = "multiselect" })%> 
      <%: Html.ValidationMessageFor(model => model.Problem.Users)%> 
     </div> 

     <p> 
      <input type="submit" class="button" value="Save" /> 
     </p> 

<% } %> 

然而,当我提交输入了[HttpPost]编辑控制器动作,但与空为广大值的形式...

[HttpPost] 
    public ActionResult Edit(Problem problemValues) 
    { 
     try 
     { 
      MembershipUser myObject = Membership.GetUser(); 
      String UserId = myObject.ProviderUserKey.ToString(); 

      Problem problem = problemValues.ProblemId == 0 
       ? new Problem() 
       : sqlProblemRepository.Problems(UserId).First(p => p.ProblemId == problemValues.ProblemId); 
      TryUpdateModel(problem); 

      if (ModelState.IsValid) 
      { 
       sqlProblemRepository.SaveProblem(problem); 
       TempData["message"] = problem.ProblemId + " has been saved."; 

       if (Request.IsAjaxRequest()) 
       { 
        return Json(problem); 
       } 

       return RedirectToAction("Details", "Student", new { problem.StudentId }); 
      } 
      else 
       return View(problem); 
     } 
     catch (Exception ex) 
     { 
      if (Request.IsAjaxRequest()) 
      { 
       return Json(null); 
      } 
      else 
      { 
       TempData["message"] = "Record Not Found."; 
       return RedirectToAction("Index"); 
      } 
     } 
    } 

alt text

在这个任何想法,将APPR eciated它似乎发生在我有大多数形式的下拉列表,但我不明白为什么所有的值都是空的,即使是非下拉字段。

在此先感谢...

乔纳森

+4

进入viewmodel ...这是一个代码气味 – 2010-09-02 10:54:58

+0

感谢您的意见。我对ASP.NET MVC很陌生。我只是想出了一个解决方案来实现它。我想我应该在控制器中填充SelectLists所需的列表,然后将它们传递给viewModel。 – 2010-09-02 11:04:38

回答

2

我会建议您保持您的存储库与模型分开。这样,你传递给视图的就是模型。 View和ViewModel都不需要任何存储库。它的工作方式是控制器使用的存储库,以获取模型,这个模型传递给视图:

public ViewResult Create() 
{ 
    string username = User.Identity.Name; 
    Problem model = someRepository.FetchModel(username); 
    ProblemViewModel viewModel = someMapper.ConvertToViewModel(model); 

    return View("Edit", viewModel); 
} 

并提交行动:我注意到你正在通过你的回购更深的挖掘之前

[HttpPost] 
public ViewResult Create(ProblemViewModel viewModel) 
{ 
    // viewModel will contain all the fields that you have corresponding 
    // inputs in the View 
    ... 
} 
+0

如果我更改我的控制器动作头到[HttpPost] public ViewResult Edit(ProblemViewModel viewModel)我得到:没有为此对象定义的无参数构造函数。 – 2010-09-02 11:34:01

+1

是的,这很正常。你必须删除你的构造函数,因为它不再有任何意义。 – 2010-09-02 11:44:00

+0

虽然这确实提供了一个解决方案,'重写所有东西,使它更像X',这不是解决您发布的问题的方法...... – 2010-09-02 12:56:16

0

我想你需要你的编辑操作的签名更改为

[HttpPost] 
public ActionResult Edit(int problemId, Problem problemValues) 
{ 
. 
. 
} 

看来你有同样的问题在这里提到MVC Custom ViewModel and auto binding

1

如果你检查生成的html,我想你会发现表单域使用点符号..基本上发布回model.Prob LEM而不只是问题......潜藏你......呃....问题

编辑 我没有做一个伟大的工作,解释这一点,我觉得....你的HTML字段应该回发将映射到动作所接受的模型的属性,在这种情况下,动作需要一个Problem模型....但是,您的html字段会发回一个有问题的模型......而不是一个问题。

+0

我检查了我的HTML,我不认为我有模型。问题: 都是问题。 – 2010-09-02 11:06:29

+2

恰恰相反,那是你的问题。这些字段为了正确映射,应该只是ProblemId,StudentId,CommunicationTypeId等...而不是Problem.XXXX – 2010-09-02 12:25:31

+1

解决方案是使用其他Htmlhelper重载,因此插入<%:Html.HiddenFor(model = > model.Problem.ProblemId)%>你会使用<%:Html.Hidden(“ProblemId”,Model.Problem.ProblemId)%> – 2010-09-02 12:52:21