2016-03-27 14 views
-1

Oluşturma Eylemim için Post Denetleyiciyle bazı sorunlar yaşıyorum. Aşağıda benim modelleri, Yuvarlak, Malzeme, MaterialShape, RawMaterial. Ana hedefim, veritabanına Round nesnesi eklemektir.ViewModel DropDownList ve HTTP Post Controller

public class Material 
{ 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ID { get; set; } 

    [Required] 
    [Display(Name="Material")] 
    public string MaterialName { get; set; } 
} 

Malzeme için Özet Sınıf I görünümüne tüm Materyalleri getirmek için oluşturulan Görünüm Modeli Yuvarlak Aşağıda

[Table("Rounds")] 
public class Round : MaterialShape 
{ 
    [Required] 
    [Display(Name="Outside Diameter")] 
    public double OuterDiameter { get; set; } 
} 

MaterialShape

dan Class Kalıtsal

public abstract class MaterialShape 
{ 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int Id { get; set; } 


    [Required] 
    public virtual Material Material { get; set; } 
} 

edilir şekil ver. Tüm farklı materyalleri veritabanından getirmek için IEnumerable kullandım. Ayrıca, seçilen öğeyi tutmak için bir MaterialId ekledim. Eğer ben veritabanına listesini alma gerçekleştirilir görebileceğiniz gibi Kontrolör Eylem

public ActionResult Create() 
     { 
     var model = new VMRoundMaterial(); 
     using (var db = new DbContext()) 
     { 
      model.Materials = db.Materials.ToList().Select(x => new SelectListItem 
      { 
       Value = x.ID.ToString(), 
       Text = x.MaterialName 
      }); 
     } 
     return View(model); 
    } 

oluştur Görünüm

@model SetupSheet.Models.ViewModel.VMRoundMaterial 

@{ 
ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 


@using (Html.BeginForm()) 
{ 
@Html.AntiForgeryToken() 

<div class="form-horizontal"> 
    <h4>Round</h4> 
    <hr /> 
    @Html.ValidationSummary(true) 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Round.OuterDiameter, new { @class = "control-label col-md-2" }) 

     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Round.OuterDiameter) 
      @Html.ValidationMessageFor(model => model.Round.OuterDiameter) 


     </div> 
    </div> 
    <div class="form-group"> 
     @Html.LabelFor(model => model.Materials, new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownListFor(m => m.MaterialId, Model.Materials) 
     </div> 
    </div> 

    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Create" class="btn btn-default" /> 
     </div> 
    </div> 
    </div> 
    } 

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

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

Round Create View with Combobox from Database

oluştur

public class VMRoundMaterial 
{ 
    public Round Round { get; set; } 

    [Display(Name="Material")] 
    public IEnumerable<SelectListItem> Materials { get; set; } 

    public int MaterialId { get; set; } 
} 

. Viewmodel'i [Post] Oluşturma Eylemi'ndeki Datamodel'e geri dönüştürme ile ilgili sorunlar yaşıyorum.

[HttpPost] 
    public ActionResult Create(VMRoundMaterial viewmodel) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 
       Round roundmaterial = new Round(); 

       roundmaterial.OuterDiameter = viewmodel.Round.OuterDiameter; 
       roundmaterial.Material.ID = viewmodel.MaterialId; 
       db.Rounds.Add(roundmaterial); 
       db.SaveChanges(); 
      } 

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

Viewmodel null Benim [HttpPost] düzgün çalışmıyor. Doğru şekilde mi kurdum? DropDownListFor parametreleri düzgün ayarlanmış? Selecteditem'i Round nesnesine doğru şekilde dönüştürdüm mü? ModelState.IsValid, bir nedenden dolayı false olarak iade ediliyor. Buna neden olabilir? kod

roundmaterial.Material.ID = viewmodel.MaterialId; 

veritabanı bağlantısı çalışıyor üzerinde başarısız oluyor, ama ben sonuçlarında girmem. Çalışan olanı bulmak için başka stratejilere açığım.

jstadnicki çözüm önerisi

[HttpPost] 
    public ActionResult Create(ModelDTO viewmodel) 
    { 
     try 
     { 
      if (ModelState.IsValid) 
      { 

       Round roundmaterial = new Round(); 

       roundmaterial.OuterDiameter = viewmodel.Round.OuterDiameter; 
       roundmaterial.Material.ID = viewmodel.MaterialId; 

       db.Rounds.Add(roundmaterial); 
       db.SaveChanges(); 
      } 

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

ModelDTO Values

ModelState.IsValid = "false"

anlıyorum neden ModelDTO kullanmak istiyorum, ama hâlâ sorun yaşıyorum etmek.

ModelState hala yanlıştır. Sanırım hala burada birşeyleri kaçırıyoruz.

+0

((VMRoundMaterial ViewModel) oluşturun olduğunu başlatılmadı beri POST yöntemi içinde roundmaterial.Material.ID = viewmodel.MaterialId; kullanımınız olasılıkla bir NullReferenceException atacağım senin viewModel null? –

+0

Hayır viewmodel null değil Yukarıda eklediğim düzenlenmiş fotoğrafa bakın. – dev8989

cevap

1

ModelState geçersiz.

Genellikle düzenleme verileri için görünüm modelleri veri modelleri özellikleri içermemelidir, ve görünüm olmalıdır

public class VMRoundMaterial 
{ 
    [Required] 
    [Display(Name="Outside Diameter")] 
    public double OuterDiameter { get; set; } 
    [Display(Name="Material")] 
    public int MaterialId { get; set; } 
    public IEnumerable<SelectListItem> Materials { get; set; } 
} 

Not ayrıca görüntülü özellik bir yaratmak için int MaterialId değil IEnumerable<SelectListItem> Materials açık olması gerekiyor MaterialId ile ilişkili etiket (şu anda 'etiket' üzerine tıklamak odağı <select> öğesine ayarlamayacaktır). Sonra görünümü Yan not

@Html.LabelFor(m => m.OuterDiameter) 
@Html.EditorFor(m => m.OuterDiameter) 
@Html.ValidationMessageFor(m => m.OuterDiameter) 

@Html.LabelFor(m => m.MaterialId) 
@Html.DropDownListFor(m => m.MaterialId, Model.Materials) 
@Html.ValidationMessageFor(m => m.MaterialId) 

olacak: Ortak ActionResult olarak mülkiyet Material

0

Ben doğru size sorunu anlamak: modeldto böyle tanımlanır ModelDTO, post yönteminde VMRoundMaterial değiştirmeye çalıştığınızda:

public class ModelDTO 
{ 
    public Round Round {get;set;} 
    public int MaterialId { get; set; } 
} 

Kontrol şimdi düzgün sulu modelini alacak eğer. Görünüm modelinizde (Round) bir veri modeli kullanmanız ve gerekli Material özelliği için değerleri geri göndermediğiniz için

+0

ModelDTO bu örnekte Round. Round MaterialShape öğesinden devralınmıştır MaterialShape, Material of Material türünde bir özelliğe sahiptir. MaterialID'yi malzeme türü/nesnesi yerine datamodelde anahtar olarak kullanabilirler. blem. – dev8989

+0

Malzemelerin koleksiyonunu almazsınız. ViewModel! = DTO modelleri. HTML'de, MaterialD ile sadece bir buluyorsunuz ve ekran görüntüsünde gösterildiği gibi alıyorsunuz. Malzemelerin listesini almak için kendi kendiniz tarafından yeniden oluşturmanız gerekir. Kod doğru. – jstadnicki

+0

Bu yüzden veritabanından listeyi yenileyin ve sonra materyal türü olarak kaydedin? ModelState.IsValid neden "false"? – dev8989