.net MVC ViewModel错误-没有为此对象定义无参数构造函数

tkclm6bt  于 2023-03-31  发布在  .NET
关注(0)|答案(3)|浏览(136)

我想知道如何在Create Action上使用我的ViewModel?我尝试了几个在论坛中找到的例子,但没有解决我的问题。我已经绞尽脑汁了几天,但无法找出问题所在。
每当我单击“创建”按钮时,都会出现以下错误:没有为此对象定义无参数构造函数。

@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 -片段

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; }
    }
fjaof16o

fjaof16o1#

如果我每次看到这个问题都能得到一分钱的话。它通常与模型属性的命名以及在DropDownList中如何使用它们有关。99.999%的情况下,这是因为人们使用Html.DropDownList()并将其命名为与他们的SelectList相同。这就是应该使用强类型DropDownListFor的原因之一。
在本例中,您的问题是您有SelectList,命名为GenresArtists,那么在您的视图中您有:

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

看,名字一样。
你应该做的是改变你的模型,使SelectList命名为GenreListArtistList。然后,改变你的视图,使用强类型模型。

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

发生这种情况的原因是,您正在向控制器提交一个名为Genres的值。默认的模型绑定器尽职尽责地在模型中查找名为Genres的内容并示例化它。但是,它找到的不是ID或字符串,而是名为Genres的SelectList,当它试图示例化它时,它发现没有默认的构造函数。
因此你的错误中充满了关于同一件事的问题。

piok6c0g

piok6c0g2#

Erik Funkenbusch's answer类似,我在表单中添加了一个DropDownList,但在我的情况下,它没有(也不打算)与表单一起提交,因为它在<form></form>标签之外:

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

由于Model包含仅用于显示的字段,这也导致了No parameterless constructor defined for this object错误,因为该字段根本没有提交。
在本例中,我通过添加一个exclude绑定修复了它:

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

8qgya5xd3#

对我来说,问题出在BeginForm()方法本身,它看起来像这样:

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

从另一个项目的登录页面复制并粘贴,该页面没有下拉列表。
无论如何,从参数列表中删除模型,一切都很好:)

相关问题