9

作成アクションで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; }
    }
4

3 に答える 3

30

私がこの問題を見るたびにニッケルを持っていたら。これは通常、モデルプロパティの名前と、での使用方法に関連していますDropDownList。99.999%の確率で、人々はHtml.DropDownList()それを自分のと同じように使用して名前を付けているからSelectListです。これが、強く型付けされたを使用する必要がある理由の1つですDropDownListFor

この場合、あなたの問題はあなたがSelectList名前Genresを付けられていることですArtists、そしてあなたの見解ではあなたは以下を持っています:

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

ほら、同じ名前。

あなたがすべきことは、モデルを変更して、SelectListsに名前が付けられるようGenreListにすることArtistListです。次に、強く型付けされたモデルを使用するようにビューを変更します。

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

これが発生する理由は、Genresという値をコントローラーに投稿しているためです。デフォルトのモデルバインダーは、モデルを忠実に調べて、ジャンルと呼ばれるものを見つけてインスタンス化します。ただし、IDまたは文字列ではなく、Genresという名前のSelectListを検出し、それをインスタンス化しようとすると、デフォルトのコンストラクターがないことが検出されます。

したがって、あなたのエラー。SOはこれと同じことについて尋ねる質問でいっぱいです。

于 2012-10-03T04:10:40.420 に答える
0

Erik Funkenbuschの回答と同様に、フォームにDropDownListを追加しましたが、私の場合は、<form></form>タグの外側にあるため、フォームとともに送信されませんでした(意図されていませんでした)。

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

モデルには表示専用のフィールドが含まれていたNo parameterless constructor defined for this objectため、フィールドがまったく送信されなかったため、これもエラーの原因となりました。

この場合、除外バインディングを追加して修正しました。

public ActionResult Foo(int id, int? page, [Bind(Exclude = "MyField")]MyModel model)
于 2014-07-29T11:12:12.150 に答える
0

私にとって問題はBeginForm()メソッド自体にありました。それはこのように見えました:

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

ドロップダウンのない別のプロジェクトのログインページからコピーして貼り付けます。

とにかく、パラメータリストからモデルを削除すると、すべて正常に機能します:)

于 2015-08-07T10:24:28.983 に答える