2

ASP.NET MVCモデルバインディングはまだ私にとって新しいものであり、それがどのように機能するかを正確に理解しようとしています。現在、Html.Textbox()の機能に問題があるようです。

具体的には、「Get」と「Post」の両方でHtml.Textboxを値に設定したビューがあります。「Get」では問題なく設定されますが、ユーザーが「Post」で値を送信した後、送信された他の値に基づいて、クラスに値の1つを内部的に変更させます。

(私は基本的に一方の値をもう一方の値に基づいて検証しています...これがこれを行う正しい方法かどうかはわかりません...)

トレースすると、モデルとビューの両方で実際に値が期待どおりに変更されていることがわかりますが、「投稿」の後に画面に表示された場合、変更された値は表示されません。代わりに、元々設定されていたものです。

これが私の単純化された例です:

ビューには次の情報が表示されます。

  • SelectListのアイテムを含むドロップダウン(「その他」として事前に選択)
  • 読み取り専用のテキストボックス(プリロードされた値は0)
  • 送信ボタン

ユーザーはドロップダウンから新しい値を選択し、[送信]をクリックする必要があります。コントローラの「Post」メソッドは、ドロップダウンから新しい値を取得し、読み取り専用テキストボックスの値を変更して再表示します。

(はい、私も最終的にJQueryでこれを行う予定です...)

これが私のサンプルModelクラスです:

public class SampleSubmission
{
    public string Name { get; set; }
    public int Volume { get; set; }
    public readonly SortedList<string, int> NameVolumeList = new SortedList<string, int>();
    // Standard Constructor
    public SampleSubmission()
    {
        NameVolumeList.Add("Sample1", 10);
        NameVolumeList.Add("Sample2", 20);
        NameVolumeList.Add("Sample3", 50);
        NameVolumeList.Add("Other", 0);
        this.Name = NameVolumeList.Keys[0];
        this.Volume = NameVolumeList[Name];
    }
    // Copy Constructor
    public SampleSubmission(SampleSubmission samSub) : this()
    {
        this.Name = samSub.Name;
        this.Volume = NameVolumeList[Name];
    }
}

これがコントローラーです:

public class SampleSubmissionController : Controller
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index()
    {
        SampleSubmission sampleSub = new SampleSubmission();
        return View(sampleSub);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(SampleSubmission sampleSub)
    {
        SampleSubmission samSub = new SampleSubmission(sampleSub);
        return View(samSub);
    }
}

ビューは次のとおりです。

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<MvcModelBindTest.Models.SampleSubmission>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) {  %>
<%= Html.DropDownList("Name", new SelectList(Model.NameVolumeList.Keys.ToList())) %>
<%= Html.TextBox("Volume",Model.Volume) %>
<input type="submit" name="pick" id="pick" value="Pick" /> <% } %>
</asp:Content>

新しい値が表示されない理由について何か考えはありますか?

編集:

この問題を解決するために、「jfar」のリンクを読み、1行変更しました。

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(SampleSubmission sampleSub)
    {
        SampleSubmission samSub = new SampleSubmission(sampleSub);
        // Reset Model Value
        ModelState.SetModelValue("Volume", new ValueProviderResult(
           samSub.Volume, "", System.Globalization.CultureInfo.CurrentCulture));
        return View(samSub);
    }

これは間違いなく機能します。残念ながら、これは私にとってひどいハックのように感じます。複数のフィールドの値を更新する必要がある場合はどうなりますか?これを行うためのより良い(より単純な?)方法がなければなりません。

EDIT2:私の答えを見つけました。下記参照...

4

3 に答える 3

1

From:MVCHTMLヘルパーで定義されたテキストボックスをクリアする方法

「HTMLHelperは最初にModelStateとViewDataを調べて、キーと一致する値があるかどうかを確認し、最後に指定した値を使用します。

テキストボックスの値をリセットする必要がある場合は、一致するキーを使用してModelStateエントリもクリアする必要があります。もう1つの方法は、JavaScriptまたはMVCを使用してビューをレンダリングするのではなく、同じページにリダイレクトすることです。

于 2010-09-22T16:02:02.993 に答える
1

リセットが必要な別の変数に出くわしたとき、私は自分の質問に対する答えを見つけました。データ構造を見ていると、ModelState にキーが存在しない元の状態が必要であることがわかりました。

        ModelState.Remove(key);

「キー」は、リセットしようとしている値です。

于 2010-10-06T22:16:21.727 に答える
0

別の簡単な回避策は、代わりに

<%= Html.TextBox("Volume",Model.Volume) %>

HTML 入力タグを使用する

<input id="Volume" name ="Volume" value="@Model.Volume" />
于 2013-03-21T05:24:07.687 に答える