用于属性的ASP.NET MVC编辑器模板

前端之家收集整理的这篇文章主要介绍了用于属性的ASP.NET MVC编辑器模板前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
通常我通过@ Html.RenderModel渲染我的表单,但这次我有一个复杂的渲染逻辑,我手动渲染.我决定为一个属性创建一个编辑器模板.这是代码(从默认对象编辑器模板实现复制粘贴):
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<% var modelMetadata = ViewData.ModelMetadata; %>
<% if (modelMetadata.HideSurroundingHtml) { %>
    <%= Html.Editor(modelMetadata.PropertyName) %>
<% } else { %>
    <% if (!String.IsNullOrEmpty(Html.Label(modelMetadata.PropertyName).ToHtmlString())) { %>
        <div class="editor-label"><%= Html.Label(modelMetadata.PropertyName) %></div>
    <% } %>
    <div class="editor-field">
        <%= Html.Editor(modelMetadata.PropertyName) %>
        <%= Html.ValidationMessage(modelMetadata.PropertyName) %>
    </div>
<% } %>

这里是我如何使用它:

@Html.EditorFor(x => x.SomeProperty,"Property") //"Property" is template above

但它没有工作:标签被渲染,不管DisplayName和编辑器都没有渲染(在Watches Html.Editor(modelMetadata.PropertyName显示空字符串).我做错了什么?

解决方法

你正在编辑你的编辑.作为@ RPM1984在 this评论中转载@ darin-dmitrov答案:在给定的视图特定上下文中,您只能为运行时使用1个模板.

如果您将视图更改为渲染文本框而不是编辑器,则可以正常工作:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<% var modelMetadata = ViewData.ModelMetadata; %>
<% if (modelMetadata.HideSurroundingHtml)
   { %>
   <%= Html.Editor(modelMetadata.PropertyName) %>
<% }
   else
   { %>
   <% if (!String.IsNullOrEmpty(modelMetadata.DisplayName))
       { %>
       <div class="editor-label"><%= Html.Label(modelMetadata.PropertyName) %></div>
    <% } %>
    <div class="editor-field"><%= Html.TextBox(modelMetadata.PropertyName) %> <%= Html.ValidationMessage(modelMetadata.PropertyName) %></div>
<% } %>

如果要渲染别的东西而不是文本框(例如下拉列表),则需要确定该模型中的该属性并将其渲染.或者,如果您有更多编辑器的东西,我通常会将其解压缩到共享文件夹中的部分视图中,并使用Html.Partial(“ViewName”)

而且,无论DisplayName如何,标签都被渲染,为了防止标签在没有显示名称的情况下渲染,请将if条件更改为!String.IsNullOrEmpty(modelMetadata.DisplayName)(我已经把它放在主代码块中)

编辑
该编辑是指与object.ascx默认编辑器模板相关的问题.
这是object.ascx的代码,取自Brad Wilson’s blog

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
    <%= ViewData.ModelMetadata.SimpleDisplayText%>
<% }
   else { %>    
    <% foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit
                         && !ViewData.TemplateInfo.Visited(pm))) { %>
        <% if (prop.HideSurroundingHtml) { %>
            <%= Html.Editor(prop.PropertyName) %>
        <% }
           else { %>
            <% if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString())) { %>
                <div class="editor-label"><%= Html.Label(prop.PropertyName) %></div>
            <% } %>
            <div class="editor-field">
                <%= Html.Editor(prop.PropertyName) %>
                <%= Html.ValidationMessage(prop.PropertyName,"*") %>
            </div>
        <% } %>
    <% } %>
<% } %>

代码确实从编辑器内部调用Html.Editor,但是在一个循环中创建复杂模型属性的编辑列表.每个这些调用调用相应的编辑器(即对于字符串,它将显示string.ascx等),并且只有当你有一些“未知”的属性不是字符串,没有特定的编辑器(即byte [])它将为它调用object.ascx,但这不是调用当前属性的编辑器(你正在尝试做什么):

对象模板的主要职责是显示复杂对象的所有属性以及每个属性标签.然而,它还负责显示模型的NullDisplayText的值(如果为null),并且还负责确保只显示一个属性(也称为对象的“浅潜水”).在下一篇博文中,我们将讨论如何自定义此模板,包括执行“深度潜水”操作.

概要

简短版本:

相同属性的更多编辑基本上是功能差异的解决方案(“是/否我想要这个广播组和下拉菜单”),并且视觉差异应该使用部分视图,因为您可以尽可能多地嵌套它们,因为你明确地通过名字命名,所以没有限制,你有责任防止任何潜在的递归.

长版本:

我一直在调查,因为我有同样的问题,我使用编辑器模板渲染< li>或< td>元素(取决于配置/主题),从内部调用另一个包含标签和输入的编辑器(对于这两种情况都是相同的,但是如果属性是bool,那么输入是标签之前),我再次调用第三个模板进行输入防止复制标签/输入和输入/标签场景的代码),但这不起作用.虽然我没有找到有关msdn或其他相关源的解释,但我发现编辑器没有提供的唯一情况是当您想要为当前编辑器上下文的属性渲染编辑器(所以它实际上正是我已经引用:“在给定的视图特定上下文中,您只能在运行时使用1个模板用于给定类型”).在想了一些之后,我相信现在他们是正确的施加这个限制,因为属性x只能使用一个编辑器.您可以根据需要为属性x编辑多个编辑器,但不能使用多个模板渲染一个属性.任何渲染属性x的模板都可以使用其他模板来渲染属性x的PARTS,但是不能使用(相同或不同的)编辑器x(不同于一个)(相同的逻辑适用于具有两个或多个属性x(同一类型)和名)).

此外,如果您可以在当前模板中插入当前属性的另一个模板,那么可以链接当前属性的任意数量的模板,并且很容易导致递归,所以有一种方式会引导您进行stackoverflow

猜你在找的asp.Net相关文章