0

关于控制器操作上的模型绑定,我有两个几乎相同的场景。一种有效,一种无效。我不知道为什么。

这有效:

鉴于此 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

请注意:我省略了不相关的代码,主要是视图页面上的附加属性。我会说我没有名为“userVM”的属性,UserPersonModel就像这里的情况一样:提交表单时模型为空

更新

好的。我想我已经准备好放弃弄清楚为什么 Season 可以正确绑定,但 UserPerson 不是。

我以为我已经找到了答案,但实际上似乎并没有什么不同:

我有

Public Class SeasonCreateViewModel
    Public Property Season As Season
End Class

我有

Public Class UserCreateViewModel    
    Public UserPerson As UserPersonModel
End Class

当这样排列时,差异似乎很明显。在SeasonCreateViewModel中,我有一个Season与类同名的属性,它是 ( Season) 的实例。在其中UserCreateViewModel,我有一个属性UserPerson,它的名称与它的类稍有不同UserPersonModel。因此,我认为模型绑定器不会自动匹配userVM.UserPerson到其对应的类。

因此,我将类更改为UserPersonModelUserPerson以便表单值以与它们相同的方式匹配Season(即与类名匹配),但它仍然没有修复它。

然而,解决它的方法是,如果我改变它:

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 回答