0

コントローラー アクションでのモデル バインディングに関して、ほぼ同じシナリオが 2 つあります。1つは機能し、1つは機能しません。理由がわかりません。

これは機能します:

この ViewModel クラスが与えられた場合:

Public Class SeasonCreateViewModel
    Public Property Season As Season
End Class

私たちはこれらのアクションを持っています

Function Create() As ActionResult
    Dim seasonVM As New SeasonCreateViewModel()
    Return View("Create", seasonVM)
End Function

<HttpPost()>
<ValidateAntiForgeryToken()>
Function Create(seasonVM As SeasonCreateViewModel) As ActionResult
End Function

そして、すべてが完全に結合します。 seasonVM.Seasonフォームから投稿された値が含まれます。

ただし、これは機能しません。

この ViewModel クラスが与えられた場合:

 Public Class UserCreateViewModel    
        Public UserPerson As UserPersonModel
 End Class

そして、これらのアクション:

    Function Create() As ActionResult
        Dim userVM As New UserCreateViewModel()
        Return View("Create", userVM)
    End Function

    '
    ' POST: /Admin/User/Create

    <HttpPost()>
    <ValidateAntiForgeryToken()>
    Function Create(userVM As UserCreateViewModel) As ActionResult
    End Function

userVM.UserPerson同じようにフォームの値にバインドしませんseasonVM.Season。実はNothing(通称null

誰にもアイデアはありますか?

ビューに興味がある場合は、次のように同じ構造になっています。

@Using Html.BeginForm()
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(True)
        <div class="editor-label">
            @Html.LabelFor(Function(model) model.UserPerson.NewUsername)
        </div>
        <div class="editor-field">
            @Html.EditorFor(Function(model) model.UserPerson.NewUsername)
            @Html.ValidationMessageFor(Function(model) model.UserPerson.NewUsername)
        </div>
<p>
            <input type="submit" value="Create" />
        </p>
End Using

@Using Html.BeginForm()
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(True)
        <div class="editor-label">
            @Html.LabelFor(Function(model) model.Season.SeasonDescription)
        </div>
        <div class="editor-field">
            @Html.EditorFor(Function(model) model.Season.SeasonDescription)
            @Html.ValidationMessageFor(Function(model) model.Season.SeasonDescription)
        </div>
<p>
            <input type="submit" value="Create" />
        </p>
End Using

注意: 関係のないコードは省略しました。ほとんどの場合、ビュー ページの追加のプロパティのみです。UserPersonModelここの場合のように、「userVM」という名前のプロパティはありません。フォームが送信されたときにモデルがnullです

アップデート

わかった。Season が適切にバインドされている理由を理解することをあきらめる準備ができていると思いますが、UserPerson はそうではありません。

私は答えを見つけたと思っていましたが、実際には違いはないようでした:

私は持っている

Public Class SeasonCreateViewModel
    Public Property Season As Season
End Class

そして、私が持っています

Public Class UserCreateViewModel    
    Public UserPerson As UserPersonModel
End Class

こうして並べてみると、違いが一目瞭然。には、( ) のインスタンスであるクラスと同じ名前SeasonCreateViewModelのプロパティがあります。には、クラスとは少し異なる名前のプロパティがあります。このため、モデル バインダーが対応するクラスに自動的に一致しないと考えました。SeasonSeasonUserCreateViewModelUserPersonUserPersonModeluserVM.UserPerson

そのため、フォームの値が同じように(つまり、クラス名に)一致するようにクラスUserPersonModelを変更しましたが、それでも修正されませんでした。 UserPersonSeason

ただし、これを変更すると、次のように修正されます。

Function Create(userVM As UserCreateViewModel) As ActionResult

これに

Function Create(userPerson As UserPerson) As ActionResult

以前はそうではなかったのに、なぜこれが突然適切にバインドされるのでしょうか? 何も思いつきません。しかし、これは誰かがこの質問に答えるのに役立ちますか?

4

2 に答える 2

0

私が理解しているように、あなたは の新しいインスタンスを作成していませんUserPersonModel。私は非常に間違っている可能性があります:)

Public Class UserCreateViewModel    
    Public UserPerson As UserPersonModel
End Class

あなたの行動では、次のようなことをすべきだと思います:

Function Create() As ActionResult
    Dim userVM As New UserCreateViewModel()

    //userVM.UserPerson = new UserPersonModel() -- in c#
    //userVM.UserPerson As New UserPersonModel() -- in VB?

    Return View("Create", userVM)
End Function

または、この回答を無視してください:P

于 2013-02-14T21:05:14.953 に答える
0

私は以前にこれに出くわしましたが、答えはまったく明白ではありませんが、知った後は理にかなっています. モデル全体 (静的タイプではなく) をバインドする場合、そのモデルのすべてのメンバーをフォームに投稿する必要があります。そうしないと、モデルバインダーは投稿された値をモデルのインスタンスとして認識しません。

すべてのメンバーを投稿するのではなく、サブセットだけを投稿したい場合は、投稿したいフィールドだけでビューモデルを作成し、AutoMapper などを使用するか、実際のモデルのフィールドを手動でマップする必要がありますあなたの POST アクション。

于 2013-02-14T21:09:26.877 に答える