【问题标题】:ASP.MVC 3 Razor Add Model Prefix in the Html.PartialView extensionASP.MVC 3 Razor 在 Html.PartialView 扩展中添加模型前缀
【发布时间】:2011-02-04 13:10:53
【问题描述】:

我和他有很多相同的问题ASP.NET MVC partial views: input name prefixes

我正在尝试为此数据实体创建 CRUD 操作:

public class UserViewModel 
{  
   protected virtual Id {get; set;} 
   public virtual string Login { get; set; }
   public virtual string Password { get; set; }
   public virtual ZipCodeViewModel ZipCode { get; set; }
}

邮政编码实体:

public class ZipCodeViewModel
{        
   public virtual string City { get; set; }

   public virtual string State { get; set; }           

   public virtual string Zip { get; set; }
}

我也有使用 UserViewModel.ZipCode 的部分视图 ZipCode:

@model ZipCodeViewModel    

    @Html.TextBoxFor(x => x.Zip, new { id = "ZipCode", name = "ZipCode.Zip", maxlength = "5" })     

我将在另一个页面(例如用户)中使用 ZipCodePartialView。

@model UserViewModel
.....
@{Html.RenderPartial("Zipcode", Model.ZipCode);}

当 MVC 保存用户 ZipCode 字段时 Zip 为空。

那么问题是如何将模型前缀添加到父视图?

【问题讨论】:

  • 你如何加载你的对象?你的ISession打开了吗?你使用延迟加载吗?
  • 你是说来自 ZipCode 的数据永远不会进入渲染页面?或者您是说当您回传数据时,数据永远不会填充到模型中?
  • 来自 ZipCode 的所有数据总是将其引入呈现的页面。
  • stackoverflow.com/questions/1488890/…找到更好的答案

标签: asp.net-mvc-3 razor


【解决方案1】:

试试这个扩展:

public static void RenderPartialWithPrefix(this HtmlHelper helper, string partialViewName, object model, string prefix)
        {
            helper.RenderPartial(partialViewName,
                                 model,
                                 new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = prefix } });
        }

【讨论】:

    【解决方案2】:

    不要使用Html.RenderPartial(),而是将您的部分视图放在Shared/EditorTemplates/ 中并将其命名为类型的名称(在本例中为ZipCodeViewModel)。然后您可以使用Html.EditorFor() 传递属性的表达式。 EditorFor() 正确地为字段添加前缀,以便 MVC 中的模型绑定器可以正确地放置您的数据。

    像这样的

    @model UserViewModel
    .....
    @Html.EditorFor(m => m.ZipCode);
    

    我会尝试挖掘一些链接和资源,但想为你找到答案。

    编辑: 这篇博文似乎涵盖了 EditorFor() 扩展和 EditorTempaltes 的基础知识:Quick Tips About ASP.NET MVC: Editor Tempaltes

    无论如何,当您使用Html.TextBoxFor()Html.DropDownFor() 扩展时,它们所做的就是从您传入的表达式中获取属性的全名,并将HTML 输入元素的名称和id 属性设置为该名称。示例可能是:

    @Html.TextBoxFor(m => m.Person.FirstName)
    

    会渲染

    <input id="Person_FirstName" name="Person.FirstName" type="text" value="<what ever was in FirstName>" />
    

    那些输入名称和值是发布数据中的键/值对。默认的 ASP.NET MVC 模型绑定器尝试将这些键与您的控制器操作所采用的模型进行匹配。如果它可以找到匹配项,那么它会设置该值。

    所以您上面的问题可能是因为您的局部视图中的输入名称是从ZipCodeViewModel 向下但您的操作是在UserViewModel 中进行的。 EditorFor() 为您的名称添加前缀,因此它基本上可以呈现一个局部视图,该视图将返回可以为您绑定的数据。尽管您可以自己在输入元素上设置名称属性(或者按照您在 cmets 中的建议展平所有内容),但其中有这些帮助程序可以为您完成。

    我希望这有助于解释正在发生的事情以及可能的解决方案。

    【讨论】:

    • 我可以将我的 ZipCode 模型中的字段添加到 User 模型中,一切正常。但随后我必须在视图中创建 ZipCode 视图。这不是 MVC 的良好实现。我会得到类似 UserControl 的东西,我可以在程序的各个地方使用它。
    • 如果你不需要/不想弄乱你的用户模型,我建议不要弄乱你的用户模型,并且 EditorFor() 助手与 EditorTemplates 创建一个可重用的局部视图。我相信这就是你所追求的。
    • 感谢您的回答,但这个解决方案对我没有好处。 EditorFor() 助手不允许使用控制器。我的部分观点有自己的逻辑。我必须这样做 - stackoverflow.com/questions/1488890/…
    • 糟糕!这正是我要寻找的。​​span>
    【解决方案3】:

    事实证明,EditorTemplates 是要走的路。 (本帖第一条评论:http://thatextramile.be/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc

    只需将 ZipCodeViewModel.cshtml 添加到 EditorTemplates 文件夹,如果需要,该文件夹可以位于 Views/Shared 中。然后使用 @Html.EditorFor(m => m.ZipCode)。像魔术一样工作。

    【讨论】:

      【解决方案4】:

      你可以如下代码:

      ActionResult MyAction(UserViewModel model)
      {
          TryUpdateModel(model.ZipCode);
      }
      

      所以模型会更新两次。第二次为你的部分。

      【讨论】:

        猜你喜欢
        • 2019-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-30
        • 1970-01-01
        相关资源
        最近更新 更多