MVC视图模型错误 - 此对象定义无参数的构造函数视图、函数、义无、模型

2023-09-03 12:44:14 作者:我醉欲眠

我想知道我可以用我的视图模型的创建操作?我想我在论坛发现这里的几个例子,但是没有解决我的问题。我一直在货架我的大脑了几天,但无法弄清楚什么是错的。

每当我点击创建按钮,我得到以下错误: 无参数的构造函数定义为这个对象。

  @model MvcMusicStore.ViewModels.AlbumViewModel

@ {
    ViewBag.Title =创建;
}

< H2>创建< / H>

<脚本SRC =@ Url.Content(〜/脚本/ jquery.validate.min.js)类型=文/ JavaScript的>< / SCRIPT>
<脚本SRC =@ Url.Content(〜/脚本/ jquery.validate.unobtrusive.min.js)类型=文/ JavaScript的>< / SCRIPT>

@using(Html.BeginForm()){
    @ Html.ValidationSummary(真)
    <字段集>
        <传奇>相册和LT; /传说>

        < D​​IV CLASS =编辑标记>
            @ Html.LabelFor(型号=> model.AlbumItem.GenreId,流派)
        < / DIV>
        < D​​IV CLASS =主编场>
            @ Html.DropDownList(流派,的String.Empty)
            @ Html.ValidationMessageFor(型号=> model.AlbumItem.GenreId)
        < / DIV>

        < D​​IV CLASS =编辑标记>
            @ Html.LabelFor(型号=> model.AlbumItem.ArtistId,艺术家)
        < / DIV>
        < D​​IV CLASS =主编场>
            @ Html.DropDownList(艺术家,的String.Empty)
            @ Html.ValidationMessageFor(型号=> model.AlbumItem.ArtistId)
        < / DIV>

        < D​​IV CLASS =编辑标记>
            @ Html.LabelFor(型号=> model.AlbumItem.Title)
        < / DIV>
        < D​​IV CLASS =主编场>
            @ Html.EditorFor(型号=> model.AlbumItem.Title)
            @ Html.ValidationMessageFor(型号=> model.AlbumItem.Title)
        < / DIV>

        < D​​IV CLASS =编辑标记>
            @ Html.LabelFor(型号=> model.AlbumItem.Price)
        < / DIV>
        < D​​IV CLASS =主编场>
            @ Html.EditorFor(型号=> model.AlbumItem.Price)
            @ Html.ValidationMessageFor(型号=> model.AlbumItem.Price)
        < / DIV>

        < D​​IV CLASS =编辑标记>
            @ Html.LabelFor(型号=> model.AlbumItem.AlbumArtUrl)
        < / DIV>
        < D​​IV CLASS =主编场>
            @ Html.EditorFor(型号=> model.AlbumItem.AlbumArtUrl)
            @ Html.ValidationMessageFor(型号=> model.AlbumItem.AlbumArtUrl)
        < / DIV>

        &其中p为H.;
            <输入类型=提交值=创建/>
        &所述; / P>
    < /字段集>
}

< D​​IV>
    @ Html.ActionLink(返回目录,目录)
< / DIV>
 

Create.cshtml

 公共类StoreManagerController:控制器
        {
            私人MusicStoreDB DB =新MusicStoreDB();

            //
            // GET:/ StoreManager /创建

            公众的ActionResult创建()
            {
                VAR视图模型=新AlbumViewModel()
                {
                    流派=新的SelectList(db.Genres,GenreId,姓名),
                    艺术家=新的SelectList(db.Artists,ArtistId,姓名)
                };
                返回视图(视图模型);
            }

            //
            //邮编:/ StoreManager /创建

            [HttpPost]
            公众的ActionResult创建(AlbumViewModel VM)
            {
                如果(ModelState.IsValid)
                {
                    db.Albums.Add(vm.AlbumItem);
                    db.SaveChanges();
                    返回RedirectToAction(指数);
                }

                vm.Genres =新的SelectList(db.Genres,GenreId,姓名,vm.AlbumItem.GenreId);
                vm.Artists =新的SelectList(db.Artists,ArtistId,姓名,vm.AlbumItem.ArtistId);
                返回查看(VM);
            }
}
 

StoreManager.cs - 段

 公共类AlbumViewModel
    {
        公共AlbumViewModel()
        {
            //什么
        }

        公共专辑AlbumItem {获得;组; }
        公众的SelectList流派{获得;组; }
        公众的SelectList艺术家{获得;组; }
    }

公共类专辑
    {
        公共相册()
        {
            //什么
        }

        公共虚拟INT ALBUMID {获得;组; }
        公共虚拟INT GenreId {获得;组; }
        公共虚拟INT ArtistId {获得;组; }
        公共虚拟字符串名称{获取;组; }
        公共虚拟十进制价格{获得;组; }
        公共虚拟字符串AlbumArtUrl {获得;组; }
        公共虚拟体裁类型{获取;组; }
        公共虚拟艺术家艺术家{获得;组; }
    }

公共类艺术家
    {
        公共艺术家()
        {
            //什么
        }

        公共虚拟INT ArtistId {获得;组; }
        公共虚拟字符串名称{;组; }
    }

公共类体裁
    {
        公共类型()
        {
            //什么
        }

        公共虚拟INT GenreId {获得;组; }
        公共虚拟字符串名称{;组; }
        公共虚拟字符串描述{获得;组; }
        公共虚拟目录<相册和GT;专辑{获得;组; }
    }
 
Java开发人员经常犯的10大错误

如果我有一个镍为每一位我已经看到了这个问题的时候解决方案

。它通常涉及到你的模特属性的命名以及如何使用它们的的DropDownList 。 99.999%的时间,那是因为人都是用 Html.DropDownList()并将其命名为与它们的的SelectList 。这是你应该使用的原因之一强类型 DropDownListFor

在这种情况下,你的问题是,你有的SelectList 的named 流派艺术家,那么在你看来,你有:

  @ Html.DropDownList(流派,的String.Empty)
@ Html.DropDownList(艺术家,的String.Empty)
 

见,同样的名字。

你应该做的是改变你的模型,使的SelectList s为单位命名为 GenreList ArtistList 。然后,更改您的视图使用强类型的模型。

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

出现这种情况的原因是,你要发送一个名为流派控制器值。默认的模型绑定尽职尽责地看在模型中找到一些所谓的流派并创建实例。但是,而不是一个ID或字符串,它发现的选择列表命名的流派,而当它试图实例化它,它发现没有默认的构造函数。

这样的错误。所以充满了疑问询问同样的事情。

I would like to know how can I use my ViewModel on the Create Action? I tried several examples I found here in the forum, but none solved my problem. I've been racking my brain for a few days, but can't figure out what is wrong.

Whenever I click the Create button I get the following error: No parameterless constructor defined for this object.

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

解决方案

If I had a nickel for every time I've seen this problem. It's typically related to the naming of your model properties and how you use them in a DropDownList. 99.999% of the time it's because people are using Html.DropDownList() and naming it the same as their SelectList. This is one reason you should use the strongly typed DropDownListFor.

In this case, your problem is that you have SelectLists named Genres and Artists, then in your view you have:

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

See, same name.

What you should do is change your Model to make the SelectLists be named GenreList and ArtistList. Then, change your view to use strongly typed model.

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

The reason this happens is that you are posting a value called Genres to the controller. The default model binder dutifully looks in the model to find something called Genres and instantiate it. But, rather than an ID or string, it finds a SelectList named Genres, and when it tries to instantiate it, it finds there is no default constructor.

Thus your error. SO is filled with questions asking about this same thing.