2

モデルをビューモデルにバインドしようとして問題が発生しました。

したがって、基本的なビューモデルは次のとおりです。

public class RegistrationVM
{
    public TravelHistoryVM TravelHistory {get;set;}
    public UserDetailVM UserDetails {get;set;}
    public ICollection<HandsetDevicesVM> ExistingDevices {get;set;}
}

さらに3つのビューモデルのラッパーで、それぞれに通常の文字列、int、boolのバンドが含まれています。今のところHandsetDevicesVMのコレクションは無視してください。

私は次のビューを持っています(明確にするためのサンプル)

@using (Html.BeginForm())
{
    @Html.ValidationSummary(false)

    @Html.LabelFor(model => model.TravelHistory.DoNotTravel)
    @Html.CheckBoxFor(model => model.TravelHistory.DoNotTravel)

    @Html.EditorFor(model => model.UserDetails, "UserDetailsHidden")
}

'TravelHistory'オブジェクトは正常にバインドされており、問題はありません。'UserDetails'オブジェクトは、データがポストバックされるときに常にnullになります。

テンプレートは間違いなくレンダリングされています。HTMLからわかります。テンプレート自体を以下に示します。

@model Foo.Bar.UserDetailVM
@Html.HiddenFor(model => model.EmailAddress)
@Html.HiddenFor(model => model.FirstName)
@Html.HiddenFor(model => model.Surname)
@* etc etc *@

生成されるHTMLは

<input data-val="true" data-val-required="The Email Address field is required." id="UserDetails_EmailAddress" name="UserDetails.EmailAddress" type="hidden" value="stack@overflow.com" />
<input data-val="true" data-val-required="The First Name field is required." id="UserDetails_FirstName" name="UserDetails.FirstName" type="hidden" value="Stack" />
<input data-val="true" data-val-required="The Surname field is required." id="UserDetails_Surname" name="UserDetails.Surname" type="hidden" value="Overflow" />

このEditorTemplateを別のビューで問題なく使用しています(そのビューモデルに問題なくバインドされます)。

最後に、Fiddlerを使用して、情報が投稿されていることを確認できます。

UserDetails.EmailAddress=stack%40overflow.com.test&UserDetails.FirstName=stack&UserDetails.Surname=overflow

何か案は?デバッグ作業をどこに集中させる必要がありますか?

Edit1:ModelStateオブジェクトからこれに気づきました

AttemptedValue: 'Foo.Bar.UserDetailVM'

したがって、文字列値'Foo.Bar.UserDetailVM'をオブジェクトにバインドしようとしていて、(明らかに)失敗しているようです。

Edit2:

[HttpPost]
public ActionResult Travel(RegistrationVM model)

要求に応じて、私が投稿しているアクション

Edit3:

ああ..ステージに戻ってOK、これはビューを提供するアクションメソッドです

[HttpGet]
public ActionResult Travel(PreRegistrationVM model)
{
    if (TempData["PreRegistrationVM"] != null)
    {
        model = (PreRegistrationVM)TempData["PreRegistrationVM"];
    }
    var newModel = new RegistrationVM(model);
    return View(newModel);
}

これは私が使用しているものです(したがって、機能しないプロセスの一部でした)。基本的に、前のステップからの情報はTempDataに保存され、このメソッドで取得されます。次に、上記のようにVMをインスタンス化するために使用されます。この時点で(ここにブレークポイントを挿入した場合)、モデルには期待どおりのデータが入力されます。

私がそれを次のように修正した場合:

[HttpGet]
public ActionResult Travel(PreRegistrationVM model)
{
    var newModel = new RegistrationVM 
    {
        FirstName = "Stack",
        Surname = "Overflow"
    };
    return View(newModel);
}

期待通りにバインドします。ここでTempDataが原因ですか?

4

1 に答える 1

0

クイックバックグラウンドチェック:これは、「ウィザード」のステップバイステップの登録プロセスの作成中に発生した問題でした。登録が完了するまで、データベースに情報を保存しないようにしたかったのです。したがって、TempDataコレクションを使用してアクション間の情報を格納し、RedirectToActionを使用してステップ間を移動するというアイデアがありました。

その価値のために、私はそのようにTempDataを使用することからメソッドを修正しました

[HttpGet]
public ActionResult Travel(PreRegistrationVM model)
{
    if (TempData["PreRegistrationVM"] != null)
    {
        model = (PreRegistrationVM)TempData["PreRegistrationVM"];
    }
    var newModel = new RegistrationVM(model);
    return View(newModel);
}

登録プロセスのステップごとに1回、データベースから情報を取得します。

[HttpGet]
public ActionResult Travel(int id)
{
    var model = FooRepository.GetById(id);
    return View(model);
}

TempDataアプローチがなぜこれをもたらしたのか完全にはわかりませんが、私が理由を提供するよりも多くのことを学んだ人々に興味があるでしょう。

答えてくれたすべての人に感謝し、私がそれを追跡するのを手伝ってくれました。

于 2012-04-23T20:24:19.793 に答える