10

次のPOCOクラスがあります。

public class Location
    {
        public int LocationId { get; set; }
        public string Name { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
        public float? Latitude { get; set; }
        public float? Longitude { get; set; }
        public string PhoneNumber { get; set; }
        public string EmailAddress { get; set; }
        public string Website { get; set; }
        public virtual ICollection<Program> Programs { get; set; }
        public virtual ICollection<PlayerType> PlayerTypes { get; set; }
    }

public class PlayerType
    {
        public int PlayerTypeId { get; set; }
        public string Name { get; set; }
        public int SortOrder { get; set; }
        public bool IsActive { get; set; }
        public virtual ICollection<Location> Locations { get; set; }
    }

そしてビューモデルクラス

public class LocationViewModel
    {
        public Location Location { get; set; }
        public IList<PlayerType> SelectPlayerTypes { get; set; } 

        public LocationViewModel()
        {
            Location = new Location();
        }

    }

作成フォーム内で、モデルを次のように定義しました

@model Locator.Models.LocationViewModel

そして、次のようなフィールドがあります。

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

私のコントローラーでPOSTを処理します

[HttpPost]
        public ActionResult Create(LocationViewModel location)
        {
            if (ModelState.IsValid) {
                locationRepository.InsertOrUpdate(location.Location);
                locationRepository.Save();
                return RedirectToAction("Index");
            }
            location.SelectPlayerTypes = golferTypeRepository.All.Where(p => p.IsActive).ToList();
            return View(location);
        }

問題は、Locationオブジェクトがありますが、フォームに入力された値に設定されるプロパティがないことです。

私はここで何か間違ったことをしていますか?

ありがとう

4

10 に答える 10

51

ここに問題があります:

[HttpPost]
public ActionResult Create(LocationViewModel location)

見ますか?これは、アクション引数の名前です:location

ビューモデルを見てください。次の名前のプロパティがありますLocation

public Location Location { get; set; }

これはモデルバインダーを混乱させます。LocationViewModelまたはそのプロパティをバインドする必要があるかどうかはわかりません。

したがって、競合を避けるために名前を変更するだけです。

[HttpPost]
public ActionResult Create(LocationViewModel model)
于 2012-05-25T06:25:36.353 に答える
35

別の考えられる理由を提供するためだけに:コードのエラーを探すのに数時間を費やしました。私の場合、バインダーが機能しない理由は、パブリックプロパティではなくパブリックフィールドを持つモデルを使用していたためです。

public int CustomerName;

そしてそれは次のようになります:

public int CustomerName { get; set; }

ASP.NET MVCに3年間取り組んでいますが、これまでに遭遇したことはありません。それが誰かの欲求不満を救うことを願っています;)

于 2013-05-15T08:15:46.793 に答える
5

また、パーティーへの参加も遅れましたが、asp.net mvcを3年間使用した後、無効な入力が投稿されていないことに気付きました。もちろん、モデルバインダーはそれらをバインドできません。ここを参照してください:

「フォーム内の無効な要素は送信されません」。

readonly="readonly"無効にするよりも使用する方がよい。ここを参照してください。

于 2015-09-05T05:44:11.347 に答える
3

Todが言ったことを繰り返すために、モデルバインダーには、プロパティをマップするためにHTML要素に「name」属性が必要です。私は手作業で簡単なテストフォームを実行していて、要素を識別するために「id」属性のみを使用していました。

'name'属性を追加すると、すべてが適切に機能しました。

<input type="text" id="Address" name="Address" />
于 2017-06-26T09:52:11.060 に答える
2

モデルバインダーが正しく機能しないもう1つの理由をここに追加します。

ContactPhoneこのプロパティの名前をに変更することにした途中で、プロパティを持つモデルがありましたPhone。その後、新しいインスタンスを作成しようとしたときに、このプロパティの突然のモデルバインディングがすべて機能しなくなりました。

問題はCreate私のコントローラーのアクションにありました。デフォルトのVisualStudioスキャフォールディングを使用し、次のようにメソッドシグネチャを作成しました。

public ActionResult Create([Bind(Include = "Id,ContactPhone, ...")] Customer customer)
{ ... }

属性に注意してくださいBind。scaffolderは元の名前を使用してフィールドを作成しましたContactPhoneが、これは文字列であるため、リファクタリングされませんでした。新しいフィールドPhoneが含まれていなかったため、その値はモデルバインダーによって無視されました。

これで誰かの時間を節約できることを願っています。

幸運を!

于 2014-07-04T22:47:58.927 に答える
1

そして別の理由:通常、私は組み込みのエディターまたはディスプレイを使用しており、この問題が発生したことはありません。ただし、この場合、セミカスタムコントロールが必要でした。基本的に、オプションに多くのデータ属性があるドロップダウン。

私が行っていたのは、selectタグの場合です。

<select name="@Html.IdFor(x => x.SubModel.ID)" id="@Html.IdFor(x => x.SubModel)" class="form-control select-control">

今ではすべてがポストバックされており、訓練を受けていない目には、すべてが機能してバインドする必要があるように見えました。ただし、IdForヘルパーは、アンダースコアを使用してサブモデルをレンダリングします。モデルバインダーは、アンダースコアをクラス階層インジケーターとして解釈しません。それらを分離する必要があるのはドットです。NameForから来ています:

<select name="@Html.NameFor(x => x.SubModel.ID)" id="@Html.IdFor(x => x.SubModel)" class="form-control select-control">

NameForは私のすべての問題を修正しました。

于 2016-08-11T10:29:53.137 に答える
1

これでまだ問題が発生している他の人の場合、postメソッドのパラメーターにプロパティの1つと同じ名前を付けると、デフォルトのmodelbinderも失敗します。

于 2018-09-01T22:02:21.537 に答える
1

私の場合は少しユニークなケースでしたが、同じような状況で誰かに役立つことを願っています。ビューモデルにIValidatableObjectを実装しましたが、成功した場合、このインターフェイスのValidateメソッドはnullを返していました。空のIEnumerableを返す必要がありました。したがって、バインディングは実際には発生していましたが、クラッシュしていました。

基本的に、この問題が発生した場合は、Fiddlerを使用して投稿されたデータを確認し、投稿された変数がビューモデルのプロパティ(フィールドではない!)と一致することを確認し、ビューモデルコンストラクターにブレークポイントを設定して、ルーティングエンジンが正しいPOSTメソッド。幸運を!

于 2019-03-27T22:30:22.730 に答える
0

これは私の日を救った。次のようにIad:

public ActionResult Edit(int masterId, ConclusionView conclusion)

ConclusionViewという名前の物件があるConclusionので、ほとんど気が狂いました。

于 2013-04-18T09:24:28.803 に答える
0

これについてコメントするには遅すぎることを私は知っています。私がしたことは、ViewModelにパラメーターレスコンストラクターを追加したことであり、すべてが素晴らしく機能しました。

于 2015-05-23T19:19:02.680 に答える