3

戻るボタンを使用してフォームを再送信すると、ドロップダウン リストにバインドされたモデルの値が 2 回目の送信で保持されないという問題が発生します。

実際には、このコードはレポート ジェネレーターです。フォームはユーザーからパラメーターを収集し、データが表示される結果ビューに投稿します。明らかに、これは投稿するにはかなり複雑なコードですが、以下に同じバグを示す簡単なコードをいくつか示します。

私は次のようなモデルを持っています:

public class HomeModel
{
    public string SomeText { get; set; }

    public long SelectedItemId { get; set; }

    public IEnumerable<SelectListItem> AvailableItems { get; set; }

}

次のようなモデルのインスタンスを送信するフォーム:

@using(Html.BeginForm("Result", "Home", FormMethod.Get))
{
    @Html.EditorFor(model => model.SomeText)
    <br />
    @Html.DropDownListFor(model => model.SelectedItemId, Model.AvailableItems)
    <input type="submit" value="submit" />
}

そして、そのような詳細を示すビュー

You Typed: @Html.DisplayFor(model => model.SomeText) <br />

You Selected: @Html.DisplayFor(model => model.SelectedItemId)

そして、すべてを管理するコントローラー:

  public class HomeController : Controller
  {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            HomeModel model = new HomeModel();

            List<SelectListItem> items = new List<SelectListItem>();

            for (int i = 0; i < 10; i++)
                items.Add(new SelectListItem() { Value = i.ToString(), Text = i.ToString() });

            model.AvailableItems = items;


            return View(model);
        }

        public ActionResult Result(HomeModel model)
        {
            return View(model);
        }

    }

フォームに入力し、送信を押します。結果ビューにリダイレクトされ、すべて問題ありません。

次に、ブラウザをもう一度押すと、再び Index ビューが表示されます。

その後、フォームを再度送信すると、事態は悪化します。ブラウザーで以前に選択した値がリストに表示されているように見えますが、リストから選択した値がモデルに再入力されません。

文字列プロパティは正しく更新されています。これは、この動作を表示している実際のコードにも当てはまります。

これは IE でのみ発生し、バージョン 9 を使用しています。

4

2 に答える 2

1

そうです、これは間違いなくすべて正しく機能しています。

これは、検証用のスクリプト タグを挿入していた場所に関連していました。私は怠け者で、ビューの上部にそれらを貼り付けただけだったので、ページ全体が組み立てられてレンダリングされたとき、それらは本文にありました。

IE はこれに例外を持っているようで、戻るボタンを押すと、すべての検証属性とプロパティの名前の「Id」と同様に、スクリプト参照が消えました。ちょっと奇妙ですが、そこに行きます

したがって、ストーリーの教訓は、スクリプトを常に正しい場所に配置することです。

于 2013-07-16T16:35:03.180 に答える
1

さて、私は解決策を見つけました。

簡単な答え: モデル プロパティの末尾に「Id」を付けないでください

この例で最初にインデックス ビューを読み込むと、次のようにレンダリングされます。

<SELECT id=SelectedItemId name=SelectedItemId data-val-required="The field is required"...>

送信したら、戻って押してソースを確認すると、次のようになります。

<select name="SelectedItem" id="SelectedItem">

要素の名前が変更され、MVC のデシリアライザーが大幅に混乱していることに注意してください。

これは、投稿されている URL で確認できます。最初にフォームを投稿したときに、ブラウザーに表示される URL は次のとおりです。

http://localhost:57175/Home/Result?SomeText=999&SelectedItemId=1

次に、もう一度押して投稿すると、次のように表示されます。

http://localhost:57175/Home/Result?SomeText=999&SelectedItem=1

プロパティ名を変更しても問題はありませんが、問題は、目立たない検証を使用するために必要なすべての検証属性も削除されることです。誰かがそれらを保持する方法について教えてもらえますか?

于 2013-07-16T13:45:50.373 に答える