mvc.net 如何在迭代列表时使用强类型助手

发布于 2024-09-18 18:08:59 字数 791 浏览 8 评论 0原文

我有一个部分视图,它将对象列表呈现为表格格式并允许编辑值...

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<whoozit.Models.PictureModel>>" %>

<% foreach (whoozit.Models.PictureModel p in Model)
           { %>

  <td>
  <%: Html.TextBox("name",p.name) %>
  <%: Html.ValidationMessage(p.name) %>
  </td>  

<% } %>

我想重构它以利用 mvc2 中的强类型 html 帮助程序。我在理解如何创建 lambda 表达式时遇到困难,希望得到一些帮助。以下对我来说似乎不太正确。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<whoozit.Models.PictureModel>>" %>

<% foreach (whoozit.Models.PictureModel p in Model)
           { %>

  <td>
  <%: Html.TextBoxFor(???) %>
  </td>  

<% } %>

I have a partial view that renders a list of objects into a table format and allows editing of the values...

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<whoozit.Models.PictureModel>>" %>

<% foreach (whoozit.Models.PictureModel p in Model)
           { %>

  <td>
  <%: Html.TextBox("name",p.name) %>
  <%: Html.ValidationMessage(p.name) %>
  </td>  

<% } %>

I'm wanting to refactor this to take advantage of the strongly typed html helpers in mvc2. I am running into difficulty understanding how to create the lambda expressions and was hoping for some help. the following doesn't seem quite correct to me.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList<whoozit.Models.PictureModel>>" %>

<% foreach (whoozit.Models.PictureModel p in Model)
           { %>

  <td>
  <%: Html.TextBoxFor(???) %>
  </td>  

<% } %>

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

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

发布评论

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

评论(4

娇柔作态 2024-09-25 18:08:59

首先,您不应该在视图中进行迭代。迭代意味着循环,循环意味着 C#/VB.NET,视图中的 C#/VB.NET 会导致意大利面条式代码。

我建议您使用 编辑器模板。这样您就不需要在视图中编写循环。在 ~/Views/Home/EditorTemplates/PictureModel.ascx 中添加以下文件:

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<whoozit.Models.PictureModel>" %>
<td>
    <%: Html.TextBoxFor(x => x.name) %>
    <%: Html.ValidationMessageFor(x => x.name) %>
</td>

请注意,部分现在强类型为 whoozit.Models.PictureModel 而不是 IList。现在剩下的就是在主视图中包含此部分:

<%: Html.EditorFor(x => x.Pictures) %>

其中 Pictures 是主视图模型上 IList 类型的属性。这将自动调用集合中每个元素的部分,这样您就不需要在视图中编写丑陋的循环。

它只是按照惯例工作:部分需要称为 PictureModel.ascx 作为列表元素的类型名称,并位于 ~/Views/Home/EditorTemplates>~/Views/Shared/EditorTemplates 文件夹。

编辑器/显示模板将使您的视图更加优雅。

备注:在 .NET 中,约定属性名称以大写字母开头,因此我建议您将 name 属性重命名为 Name。书写和阅读感觉更自然:

<%: Html.TextBoxFor(x => x.Name) %>

First of all you shouldn't be iterating in a view. Iterating means loops, loops mean C#/VB.NET, C#/VB.NET in a view leads to spaghetti code.

I would recommend you using Editor Templates. This way you don't need to write loops in your views. Add the following file in ~/Views/Home/EditorTemplates/PictureModel.ascx:

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<whoozit.Models.PictureModel>" %>
<td>
    <%: Html.TextBoxFor(x => x.name) %>
    <%: Html.ValidationMessageFor(x => x.name) %>
</td>

Notice that the partial is now strongly typed to whoozit.Models.PictureModel instead of IList<whoozit.Models.PictureModel>. Now all that is left is to include this partial from the main view:

<%: Html.EditorFor(x => x.Pictures) %>

Where Pictures is a property of type IList<whoozit.Models.PictureModel> on your main view model. This will automatically invoke the partial for each element of the collection so that you don't need to write ugly loops in your views.

It just works by convention: the partial needs to be called PictureModel.ascx as the type name of the list elements and located in ~/Views/Home/EditorTemplates or ~/Views/Shared/EditorTemplates folder.

Editor/Display templates will make your views much more elegant.

Remark: In .NET the convention is property names to start with capital letter, so I would recommend you renaming the name property to Name. It's just feels more natural to write and read:

<%: Html.TextBoxFor(x => x.Name) %>
七分※倦醒 2024-09-25 18:08:59

您可以通过使用 for 循环遍历模型来使用强类型辅助方法。这也将使“name”html 属性变得唯一,因此模型绑定器可以帮助您在保存情况下将值映射回模型。

<% for (int i = 0; i < Model.Count; i++) { %>

  <%: Html.TextBoxFor(m => m[i].Name) %>
  <%: Html.TextBoxFor(m => m[i].SomethingElse) %>

<% } %>

在这里阅读更多内容..
http://haacked.com/archive/2008 /10/23/model-binding-to-a-list.aspx

You can use strongly typed helper methods by looping through the model with a for loop. This will also make the "name" html attribute unique so the model binder can help you map the values back to your model in a save situation.

<% for (int i = 0; i < Model.Count; i++) { %>

  <%: Html.TextBoxFor(m => m[i].Name) %>
  <%: Html.TextBoxFor(m => m[i].SomethingElse) %>

<% } %>

Read more here..
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

镜花水月 2024-09-25 18:08:59
<%= Html.TextBoxFor(p => p.name) %> 
<%= Html.TextBoxFor(p => p.name) %> 
奶茶白久 2024-09-25 18:08:59

您告诉您的部分视图需要一个 whoozit.Models.PictureModel 项目的列表。那么你的 foreach 正在寻找 whoozit.Models.Picture 而不是 PictureModel。以下是我通常会如何做这样的事情。确保您尝试枚举的列表是正确的类型。如果图片类来自 PictureModel 内的集合,请确保您在 foreach 中执行 Model.Whatever

试试这个:

<% foreach(var p in Model) { %>
<td>
<%: Html.TextBoxFor(p => p.name) %>
<%: Html.ValidateFor(p => p.name) %>
</td>
<% } %>

You are telling your partial view to expect a list of whoozit.Models.PictureModel items. Then your foreach is looking for whoozit.Models.Picture not PictureModel. Below is how I normally would do something like this. Make sure your List you are try to enumerate over is the correct type. If the picture class is coming from a collection inside the PictureModel make sure you are doing Model.Whatever in the foreach.

Try this:

<% foreach(var p in Model) { %>
<td>
<%: Html.TextBoxFor(p => p.name) %>
<%: Html.ValidateFor(p => p.name) %>
</td>
<% } %>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文