MVC 2-当模型类型为 IEnumerable/IQueryable 时更新模型数据

发布于 2024-10-07 18:28:21 字数 2930 浏览 2 评论 0原文

控制器代码:

Function ManagePages() As ActionResult
    Dim pages = contentRepository.GetAllContentPagesByType("Content Page", False)
    Return View("ManagePages", pages)
End Function

<HttpPost()> _
Function ManagePages(ByVal values As FormCollection) As ActionResult
    Dim pages = contentRepository.GetAllContentPagesByType("Content Page", False)
    ''' **** HOW DO I UPDATE THE MODEL HERE ****
    contentRepository.Save() 'Simply calls SubmitChanges()
    Return View("ManagePages", pages)
End Function

GetAllContentPagesByType 返回 IQueryable - LINQ-to-SQL 查询的结果。该视图是强类型的:

Inherits="System.Web.Mvc.ViewPage(Of IQueryable (Of DBContent))"

我循环访问视图中的每个 DBContent 对象,并为一些属性创建文本框和其他输入 - 基本上我为模型中的每个记录显示一个编辑器。这很好用。

现在我尝试了许多不同的方法来更新它:

我现在能想到的让它工作的唯一方法是循环遍历 FormCollection 参数中的所有项目,并手动更新集合中的每个 DBContent 记录,但这似乎不是最佳实践解决方案。

问题是 - 在这种情况下更新任何可枚举类型的模型的黄金标准最佳实践是什么?

编辑

如果有帮助,这里是视图的代码片段。请注意,使用 Html.TextBox 等似乎不会影响生成的表单数据。我总是得到 4 个表单键,并用逗号分隔值(基本上每个属性一个)。我尝试在这些前面加上记录 ID(唯一键),但 UpdateModel() 仍然不起作用,尽管我确实为每个输入控件获得了唯一的表单值:

<% Using Html.BeginForm%>
    <%  For Each item In Model.OrderBy(Function(c) c.DisplayOrder)%>
    <%: Html.Hidden("ContentId", Model.ContentId.ToString())%>
    <tr>
        <td class="first"><input name='Enabled' type="checkbox" checked='<%: If(Model.Enabled, "checked", "")%>' /></td>
        <td class="first"><input name='DisplayOrder' type="text" value='<%: Model.DisplayOrder %>' style="width:40px" /></td>
        <td class="first"><select name='ContentLevel'>
            <option value="100" selected='<%: If(Model.ContentLevel = 100, "selected", "") %>'>Admin</option>
            <option value="50" selected='<%: If(Model.ContentLevel = 50, "selected", "") %>'>Board</option>
            <option value="25" selected='<%: If(Model.ContentLevel = 25, "selected", "") %>'>Member</option>
            <option value="0" selected='<%: If(Model.ContentLevel = 0, "selected", "") %>'>Everyone</option>
        </select></td>
        <td><a href="EditPage/<%: Model.ContentId %>"><%: Model.PageTitle%></a></td>
        <td><%: Model.aspnet_User.UserName%></td>
        <td class="last"><%: Model.ModifiedOn%></td>
    </tr>
    <%  Next%>
<% End Using%>

Controller Code:

Function ManagePages() As ActionResult
    Dim pages = contentRepository.GetAllContentPagesByType("Content Page", False)
    Return View("ManagePages", pages)
End Function

<HttpPost()> _
Function ManagePages(ByVal values As FormCollection) As ActionResult
    Dim pages = contentRepository.GetAllContentPagesByType("Content Page", False)
    ''' **** HOW DO I UPDATE THE MODEL HERE ****
    contentRepository.Save() 'Simply calls SubmitChanges()
    Return View("ManagePages", pages)
End Function

GetAllContentPagesByType returns an IQueryable - the result of a LINQ-to-SQL query. The view is strongly typed:

Inherits="System.Web.Mvc.ViewPage(Of IQueryable (Of DBContent))"

I am looping through each of the DBContent objects in the view and creating textboxes and other inputs for a few properties - basically I am displaying an editor for each record in the Model. This works fine.

Now I've tried many different ways to get this to update:

The only way I can think of now to get it to work would be to loop through all of the items in the FormCollection parameter, and manually update each DBContent record in the collection, but that doesn't seem like a best practice solution.

The question is - what is the gold standard best practice for this scenario to update a model of any enumerable type?

Edit

If it helps, here a code snippet for the view. Note that using Html.TextBox, etc, doesn't seem to affect the resulting form data. I'm always getting 4 form keys, with comma-separated values (one for each property basically). I've tried prepending these with the record ID (unique key), but UpdateModel() still doesn't work, though I do get a unique form value for each input control:

<% Using Html.BeginForm%>
    <%  For Each item In Model.OrderBy(Function(c) c.DisplayOrder)%>
    <%: Html.Hidden("ContentId", Model.ContentId.ToString())%>
    <tr>
        <td class="first"><input name='Enabled' type="checkbox" checked='<%: If(Model.Enabled, "checked", "")%>' /></td>
        <td class="first"><input name='DisplayOrder' type="text" value='<%: Model.DisplayOrder %>' style="width:40px" /></td>
        <td class="first"><select name='ContentLevel'>
            <option value="100" selected='<%: If(Model.ContentLevel = 100, "selected", "") %>'>Admin</option>
            <option value="50" selected='<%: If(Model.ContentLevel = 50, "selected", "") %>'>Board</option>
            <option value="25" selected='<%: If(Model.ContentLevel = 25, "selected", "") %>'>Member</option>
            <option value="0" selected='<%: If(Model.ContentLevel = 0, "selected", "") %>'>Everyone</option>
        </select></td>
        <td><a href="EditPage/<%: Model.ContentId %>"><%: Model.PageTitle%></a></td>
        <td><%: Model.aspnet_User.UserName%></td>
        <td class="last"><%: Model.ModifiedOn%></td>
    </tr>
    <%  Next%>
<% End Using%>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉南桥 2024-10-14 18:28:21

您根本不会调用 UpdateModel 来更新集合。

<HttpPost()> _
Function ManagePages(ByVal values As FormCollection) As ActionResult
    Dim pages = contentRepository.GetAllContentPagesByType("Content Page", False)

    UpdateModel(pages)

    contentRepository.Save() 'Simply calls SubmitChanges()
    Return View("ManagePages", pages)
End Function

您需要按照此处的说明进行操作:
http://haacked.com/archive/2008 /10/23/model-binding-to-a-list.aspx

您的 元素名称属性需要遵循特定的语法才能正常工作。

You simply never make the call to UpdateModel to update the collection.

<HttpPost()> _
Function ManagePages(ByVal values As FormCollection) As ActionResult
    Dim pages = contentRepository.GetAllContentPagesByType("Content Page", False)

    UpdateModel(pages)

    contentRepository.Save() 'Simply calls SubmitChanges()
    Return View("ManagePages", pages)
End Function

You need to follow the instructions here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Your <input> elements name attributes need to follow a particular syntax for this to work.

时光暖心i 2024-10-14 18:28:21

我最终按照 Phil Haack 的帖子,为每个控件指定了一个唯一的名称,以索引“[0.]”作为前缀。然后,我更改了 Action 方法以接受 List(of DBContent),它正确绑定了模型数据。然后,我可以手动循环遍历集合,并手动更新每条记录。

I ended up going the route of giving each control a unique name, as per Phil Haack's post, starting with index "[0.]" as the prefix. I then changed my Action method to accept a List(of DBContent), which correctly bound the model data. I was then able to manually loop through the collection, and manually update each record.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文