2016-12-22 1 views
0

J'ai eu des problèmes avec viewmodels pendant un moment et j'aimerais clarifier quelque chose. Dans mon viewmodel, je peux montrer "index" et je peux ajouter un nouvel employé "créer", mais le "Edit" ne fonctionne pas.MVC viewmodel Edit ne montre rien après Httppost

Je peux montrer la page "éditer", faire mes modifications (comme changer le nom) mais quand je publie, toutes les données apparaissent comme null. Dans le "créer", après avoir posté l'insertion, le contrôleur affiche les modifications (EmployeeViewModel) et insère l'enregistrement. Il ne montre pas quand un "edit".

Est-ce quelque chose d'inhérent à viewmodel's ou existe-t-il autre chose?

Voilà ma classe ViewModel (base de données en premier):

public partial class Employee 
    { 
     public int EmployeeId { get; set; } 
     public string Name { get; set; } 
     public Nullable<int> DepartmentId { get; set; } 
     public string Address { get; set; } 

     public virtual Department Department { get; set; } 
    } 

public partial class Department 
    { 
     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
     public Department() 
     { 
      this.Employees = new HashSet<Employee>(); 
     } 

     public int DepartmentId { get; set; } 
     public string DepartmentName { get; set; } 

     [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
     public virtual ICollection<Employee> Employees { get; set; } 
    } 

    public class EmployeeViewModel 
    { 
     public int EmployeeId { get; set; } 
     public string Name { get; set; } 
     public Nullable<int> DepartmentId { get; set; } 
     public string Address { get; set; } 
     public string DepartmentName { get; set; } 

    } 

Voici mon contrôleur:

public class TestController : Controller 
    { 
     public db dContext = new db(); 
     public ActionResult Index() 
     { 
      List<Employee> employeelist = dContext.Employees.ToList(); 
      EmployeeViewModel employeeVM = new EmployeeViewModel(); 

      List<EmployeeViewModel> employeeVMList = employeelist.Select(x => new EmployeeViewModel 
      { 
       Name = x.Name, 
       EmployeeId = x.EmployeeId, 
       Address = x.Address, 
       DepartmentId = x.DepartmentId, 
       DepartmentName = x.Department.DepartmentName 
      }).ToList(); 
      return View(employeeVMList);  
     } 
     public ActionResult Create() 
     { 
      return View(); 
     } 
     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Create(EmployeeViewModel employeeVM) 
     { 
      if (ModelState.IsValid) 
      { 
       Employee e = new Employee(); 
       e.EmployeeId = employeeVM.EmployeeId; 
       e.Name = employeeVM.Name; 
       e.DepartmentId = employeeVM.DepartmentId; 
       e.Address = employeeVM.Address; 

       dContext.Employees.Add(e); 
       dContext.SaveChanges(); 

       return RedirectToAction("Index"); 
      } 
      return View("Index"); 
     } 

     public ActionResult Edit(EmployeeViewModel em , int? id) 
     { 
      var dbEmpVM = (from e in dContext.Employees 
          join d in dContext.Departments 
          on e.DepartmentId equals d.DepartmentId 
          where e.EmployeeId == id 
          select new EmployeeViewModel 
          { 
           EmployeeId = e.EmployeeId, 
           DepartmentId=e.DepartmentId, 
           Address=e.Address, 
           Name=e.Name, 
           DepartmentName=d.DepartmentName 
          }).ToList();  
      return View(dbEmpVM ); 
     } 

     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Edit(EmployeeViewModel model, int id) 
     { 
      string name = Request.Form["EmployeeId"]; 
      string naaanm = model.EmployeeId.ToString(); 

      return RedirectToAction("Index"); 
     } 
    } 

Et voici mon Edit:

@model IEnumerable<MVCTutorial.Models.EmployeeViewModel> 
@{ 
    ViewBag.Title = "Edit"; 
} 
<h4>(EmployeeViewModel)</h4> 
@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    foreach (var item in Model) 
    { 
<div class="form-group"> 
    @Html.LabelFor(i => item.EmployeeId, htmlAttributes: new { @class = "control-label col-md-2" }) 
    <div class="col-md-10"> 
     @Html.EditorFor(i => item.EmployeeId, new { htmlAttributes = new { @class = "form-control" } }) 
     @Html.ValidationMessageFor(i => item.EmployeeId, "", new { @class = "text-danger" }) 
    </div> 
</div> 
<div class="form-group"> 
    @Html.LabelFor(i => item.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 
    <div class="col-md-10"> 
     @Html.EditorFor(i => item.Name, new { htmlAttributes = new { @class = "form-control" } }) 
     @Html.ValidationMessageFor(i => item.Name, "", new { @class = "text-danger" }) 
    </div> 
</div> 
<div class="form-group"> 
    @Html.LabelFor(i => item.DepartmentId, htmlAttributes: new { @class = "control-label col-md-2" }) 
    <div class="col-md-10"> 
     @Html.EditorFor(i => item.DepartmentId, new { htmlAttributes = new { @class = "form-control" } }) 
     @Html.ValidationMessageFor(i => item.DepartmentId, "", new { @class = "text-danger" }) 
    </div> 
</div> 
     <div class="form-group"> 
      @Html.LabelFor(i => item.DepartmentName, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(i => item.DepartmentName, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(i => item.DepartmentName, "", new { @class = "text-danger" }) 
      </div> 
     </div> 
     <div class="form-group"> 
      @Html.LabelFor(i => item.Address, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.EditorFor(i => item.Address, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(i => item.Address, "", new { @class = "text-danger" }) 
      </div> 
     </div> 
    } 
<div class="form-group"> 
    <div class="col-md-offset-2 col-md-10"> 
     <input type="submit" value="Edit" class="btn btn-default" /> 
    </div> 
</div> 
} 
<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

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

EmployeeViewModel

Répondre

0

Votre Le code actuel (dans la vue d'édition) génère un balisage d'entrée comme ci-dessous.

<input class="form-control text-box single-line" 
     id="item_DepartmentName" name="item.DepartmentName" type="text" value="SomeName" /> 

Voir la valeur de l'attribut name. C'est "item.DepartmentName". Votre paramètre de méthode d'action HttpPost est le type EmployeeViewModel qui n'a pas de propriété avec ce nom! Le modèle de classeur ne sera donc pas en mesure de mapper les données de formulaire publiées à partir de votre formulaire portant ce nom ("item.DepartmentName") vers les propriétés de votre paramètre de méthode.

La solution consiste à mettre à jour la valeur d'attribut de votre champ de saisie pour qu'elle corresponde aux noms de propriété de votre EmployeeViewModel. Idéalement, votre code devrait générer un balisage comme ci-dessous.

<input name="DepartmentName" type="text" value="Some value" /> 

Vous pouvez spécifier le explcitily aleur d'attribut name lorsque vous appelez les aides html. Par exemple, avec l'aide Html.TextBoxFor

@Html.TextBoxFor(i => item.DepartmentName, 
           new { @class = "form-control", NAME = "DepartmentName" }) 

Maintenant, lorsque vous soumettez le formulaire, liant le modèle sera en mesure de cartographier la valeur de ce champ de formulaire à la propriété DepartmentName de votre objet EmployeeViewModel.

+0

Shyju-merci pour la réponse. Je suis toujours perdu, cependant. Le DepartmentName me va bien. Y a-t-il autre chose qui me manque? Dois-je le remplacer par "TextBoxFor" plutôt que "EditorFor" parce que c'est une classe différente (Department)? –

+0

Si vous voulez simplement entrer un champ de saisie, utilisez la méthode d'aide 'TextBoXFor'. – Shyju

+0

J'ai changé la ligne en Html.TextBoxFor (i => item.DepartmentName, nouveau {htmlAttributes = new {@class = "form-control"}}). Il montre toujours null. Y a-t-il autre chose qui ne va pas –