2012-10-03 24 views
8

Tôi muốn biết làm cách nào để sử dụng ViewModel của mình trên Tạo hành động? Tôi đã thử một số ví dụ tôi tìm thấy ở đây trong diễn đàn, nhưng không ai giải quyết được vấn đề của tôi. Tôi đã quên não trong vài ngày, nhưng không thể hiểu được điều gì là sai.MVC ViewModel Error - Không có hàm tạo tham số nào được định nghĩa cho đối tượng này

Bất cứ khi nào tôi nhấp vào nút Tạo, tôi nhận được lỗi sau: Không có hàm tạo tham số nào được xác định cho đối tượng này.

@model MvcMusicStore.ViewModels.AlbumViewModel 

@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Album</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.AlbumItem.GenreId, "Genre") 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("Genres", String.Empty) 
      @Html.ValidationMessageFor(model => model.AlbumItem.GenreId) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.AlbumItem.ArtistId, "Artist") 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("Artists", String.Empty) 
      @Html.ValidationMessageFor(model => model.AlbumItem.ArtistId) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.AlbumItem.Title) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.AlbumItem.Title) 
      @Html.ValidationMessageFor(model => model.AlbumItem.Title) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.AlbumItem.Price) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.AlbumItem.Price) 
      @Html.ValidationMessageFor(model => model.AlbumItem.Price) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.AlbumItem.AlbumArtUrl) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.AlbumItem.AlbumArtUrl) 
      @Html.ValidationMessageFor(model => model.AlbumItem.AlbumArtUrl) 
     </div> 

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

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

Create.cshtml

public class StoreManagerController : Controller 
     { 
      private MusicStoreDB db = new MusicStoreDB(); 

      // 
      // GET: /StoreManager/Create 

      public ActionResult Create() 
      { 
       var viewModel = new AlbumViewModel() 
       { 
        Genres = new SelectList(db.Genres, "GenreId", "Name"), 
        Artists = new SelectList(db.Artists, "ArtistId", "Name") 
       }; 
       return View(viewModel); 
      } 

      // 
      // POST: /StoreManager/Create 

      [HttpPost] 
      public ActionResult Create(AlbumViewModel vm) 
      { 
       if (ModelState.IsValid) 
       { 
        db.Albums.Add(vm.AlbumItem); 
        db.SaveChanges(); 
        return RedirectToAction("Index"); 
       } 

       vm.Genres = new SelectList(db.Genres, "GenreId", "Name", vm.AlbumItem.GenreId); 
       vm.Artists = new SelectList(db.Artists, "ArtistId", "Name", vm.AlbumItem.ArtistId); 
       return View(vm); 
      } 
} 

StoreManager.cs - Snippet

public class AlbumViewModel 
    { 
     public AlbumViewModel() 
     { 
      // nothing 
     } 

     public Album AlbumItem { get; set; } 
     public SelectList Genres { get; set; } 
     public SelectList Artists { get; set; } 
    } 

public class Album 
    { 
     public Album() 
     { 
      // nothing 
     } 

     public virtual int AlbumId { get; set; } 
     public virtual int GenreId { get; set; } 
     public virtual int ArtistId { get; set; } 
     public virtual string Title { get; set; } 
     public virtual decimal Price { get; set; } 
     public virtual string AlbumArtUrl { get; set; } 
     public virtual Genre Genre { get; set; } 
     public virtual Artist Artist { get; set; } 
    } 

public class Artist 
    { 
     public Artist() 
     { 
      // nothing 
     } 

     public virtual int ArtistId { get; set; } 
     public virtual string Name { get; set; } 
    } 

public class Genre 
    { 
     public Genre() 
     { 
      // nothing 
     } 

     public virtual int GenreId { get; set; } 
     public virtual string Name { get; set; } 
     public virtual string Description { get; set; } 
     public virtual List<Album> Albums { get; set; } 
    } 
+1

'Genre' là gì? – SLaks

+0

Đã thêm 'Genre' và' Artist' trên mã ở trên. – fvss

+0

Điều duy nhất dường như không có một hàm tạo tham số là SelectList (http://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist(v=vs.108).aspx). Nếu bạn bình luận thì sao? –

Trả lời

24

Nếu tôi đã có một nickel cho mỗi lần tôi đã nhìn thấy vấn đề này. Nó thường liên quan đến việc đặt tên các thuộc tính mô hình của bạn và cách bạn sử dụng chúng trong một số DropDownList. 99.999% thời gian bởi vì mọi người đang sử dụng Html.DropDownList() và đặt tên giống với số SelectList của họ. Đây là một trong những lý do bạn nên sử dụng gõ mạnh DropDownListFor.

Trong trường hợp này, vấn đề của bạn là bạn phải SelectList s tên GenresArtists, sau đó theo quan điểm của bạn, bạn có:

@Html.DropDownList("Genres", String.Empty) 
@Html.DropDownList("Artists", String.Empty) 

Xem, cùng tên.

Điều bạn cần làm là thay đổi Mô hình của mình để đặt tên s được đặt tên là GenreListArtistList. Sau đó, thay đổi chế độ xem của bạn để sử dụng mô hình được nhập mạnh mẽ.

@Html.DropDownListFor(m => m.AlbumItem.GenreID, Model.GenreList) 
@Html.DropDownListFor(m => m.AlbumItem.ArtistID, Model.ArtistList) 

Lý do điều này xảy ra là bạn đang đăng một giá trị được gọi là Thể loại cho bộ điều khiển. Các mô hình mặc định chất kết dính dutifully trông trong mô hình để tìm một cái gì đó gọi là thể loại và nhanh chóng nó. Nhưng, thay vì một ID hoặc chuỗi, nó tìm thấy một SelectList tên Genres, và khi nó cố gắng để khởi tạo nó, nó tìm thấy không có constructor mặc định.

Vì vậy, lỗi của bạn. SO được lấp đầy với các câu hỏi hỏi về điều tương tự này.

+0

Đó là nó! Cảm ơn bạn! – fvss

+0

Tương tự tại đây. Bạn đã lưu vài giờ của tôi –

0

Tương tự như Erik Funkenbusch's answer tôi đã bổ sung thêm một DropDownList mẫu của tôi, tuy nhiên trong trường hợp của tôi đó là không (và không được dự định được) nộp cùng với các hình thức như nó đã được bên ngoài của <form></form> tags:

@Html.DropDownList("myField", Model.MyField) 

Vì Mô hình chỉ chứa trường để hiển thị, điều này cũng gây ra lỗi No parameterless constructor defined for this object vì trường này chưa được gửi.

Trong trường hợp này tôi cố định nó bằng cách thêm một loại trừ ràng buộc:

public ActionResult Foo(int id, int? page, [Bind(Exclude = "MyField")]MyModel model) 
0

Đối với tôi vấn đề là trong phương pháp BeginForm() chính nó. Nó trông giống như sau:

@using (Html.BeginForm("MyAccount", "MyController", Model)) 

Sao chép và dán từ trang Đăng nhập của một dự án khác không có trình đơn thả xuống.

Dù sao, hãy xóa Mô hình khỏi danh sách tham số và tất cả chỉ hoạt động tốt :)

Các vấn đề liên quan