物业ASP.NET MVC编辑模板物业、模板、编辑、NET

2023-09-03 06:01:46 作者:疯癫小男人つ

通常我使我的形式通过@ Html.RenderModel,但这次我有一个复杂的渲染逻辑和我手动渲染。我决定创建一个编辑模板一个属性。这里是code(复制从默认对象编辑器模板执行粘贴):

Usually I render my forms by @Html.RenderModel, but this time I have a complex rendering logic and I render it manually. I decided to create a editor template for one property. Here is the code (copy pasted from default object editor template implementation):

<%@ 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>
<% } %>

这里是我如何使用它:

And here is how I use it:

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

但没有奏效:?标签呈现,无论显示名称和编辑不是在所有渲染(在手表Html.Editor(modelMetadata.PropertyName显示空字符串),我在做什么错

But it didn't work: labels are rendered regardless of DisplayName and editors are not rendered at all (in Watches Html.Editor(modelMetadata.PropertyName shows empty string). What am I doing wrong?

推荐答案

您在呼唤从你的编辑器编辑器。正如@ RPM1984 rephrases @达林 - 德米特罗夫在评论中这个回答:您只能在运行时使用1模板对于给定的类型,在给定的视图特定上下文

You are calling editor from your editor. As @RPM1984 rephrases @darin-dmitrov in comment in this answer: You can only have 1 template used at runtime for a given type, in a given Views particular context.

如果你改变你的观点来呈现的文本框,而不是编辑器,它的作品,我只是想:

If you change your view to render textbox instead of editor, it works, I just tried:

<%@ 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(视图名)

If you want to render something else instead of textbox (i.e. dropdown list), you need to decide that inside your template for that property and render it. Or, if you have something common for more editors, I usually extract that into partial view in Shared folder, and just use Html.Partial("ViewName")

和,对于的标签,无论从渲染如果没有显示名称呈现显示名称的,要prevent标签,改变你如果条件!String.IsNullOrEmpty (modelMetadata.DisplayName)(我已经把这种方式在主code座)

And, regarding labels are rendered regardless of DisplayName, to prevent label from rendering if there is no display name, change your if condition to !String.IsNullOrEmpty(modelMetadata.DisplayName) (I already put it that way in main code block)

修改 这个编辑是指问题涉及到object.ascx默认编辑模板。 这是$ C $ object.ascx的C,从Brad Wilson的博客:

EDIT This edit refers to question related to object.ascx default editor template. This is code of object.ascx, taken from 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>
        <% } %>
    <% } %>
<% } %>

这code确实是从编辑器内部调用Html.Editor,但创造的编辑为复杂的模型属性列表一个循环中。每个调用将调用相应的编辑器(如字符串,它会显示string.ascx那里等),只有当你有一些未知属性,该属性是不串并没有为它指定的编辑器(即字节[])它会调用object.ascx它,但是这是不会要求编辑为当前属性(你正在尝试做的):

This code indeed calls Html.Editor from inside of editor, but inside a loop which creates list of editors for properties of complex model. Each of these calls will invoke corresponding editor (i.e for string it will show string.ascx there etc), and only if you have some "unknown" property which is not string and there is no specific editor for it (i.e. byte[]) it will invoke object.ascx for it, but this is NOT calling editor for the current property (what you are trying to do):

的对象模板的主要职责是显示一个复杂对象的所有属性,以及每个属性的标签。然而,它也负责显示模型的NullDisplayText的价值,如果它是零,而且它也负责确保你只显示性能的一个级别(也称为对象的浅潜水)。在接下来的博客文章中,我们将讨论如何自定义此模板,包括执行深潜的操作。的

摘要

短版:

更多编辑器相同的属性基本上是功能上的差异的解决方案(对是/否我想在这里无线电集团有下拉),以及视觉上的差异部分景色应该使用,因为你可以嵌套它们尽可能多只要你想,因为你明确的名字称呼他们,所以没有限制强加的,你有责任为prevent任何潜在的递归。

More editors for same property is basically solution for functional differences ("for yes/no I want here radio group and there drop-down)", and for visual differences partial views should be used, as you can nest them as much as you want, because you explicitly call them by name so there is no limits imposed, you are responsible to prevent any potential recursions.

长版:

我一直在研究这个,因为我有同样的问题,我使用的编辑模板来呈现&LT;李&GT; &LT; TD&GT; 元素(视配置/主题),并从里面调用另外一个编辑器,其中包含标签和输入(相同的两个案件,但如果属性是布尔然后输入标签之前),在那里我' M重新调用第三方模板输入(prevent复制code的标签/输入和输入/标签的情况),但是这并不能正常工作。虽然我没有找到解释,在MSDN或其他相关人士,我想通了,当你想渲染编辑这是当前编辑的背景下,房地产(在编辑给出了什么的唯一情况是这样它实际上正是我已经引述:你只能有1模板在运行时使用给定类型,在一个给定的浏览特定的背景下。)。想更多了解这一点后,我现在相信他们是正确的气势此限制,因为楼盘X只能使用一个编辑器进行渲染。只要你想,你可以有许多编辑器属性x,但你不能渲染一个属性一次使用多个模板。您的任何模板渲染楼盘X可以使用其他模板来渲染楼盘X的部分,但不能使用(相同或不同)编辑器对于x不止一次(同样的逻辑也适用以具有两个或多个属性X(同一类型和名称)对同一型号)。

I have been investigating this, as I have the same problem, I'm using editor template to render <li> or <td> element (depending on config/theme) and from inside it call another editor which contains label and input (same for both cases, but if property is bool then input is before label), where I'm again calling third template for input (to prevent duplicating code for label/input and input/label scenarios), but this does not work. Although I did not found explanation on msdn or other relevant source, I figured out that the only scenario when editor gives nothing is when you want to render editor for the property which is the context of current editor (so it is actually exactly what I already quoted: "You can only have 1 template used at runtime for a given type, in a given Views particular context."). After thinking some more about this, I believe now that they are right in imposing this limit, as property x can only be rendered using one editor. You can have as many editors for property x as you want, but you cannot render one property once using more than one template. Any of your templates for rendering property x can use other templates to render PARTS of property x, but you cannot use (same or different) editor for x more than once (the same logic applies as to having two or more properties x (same type and name) on same model).

此外,如果你可以插入另一个模板的当前属性到当前模板,使链接任何数量的当前属性模板,极易引起递归,所以这种或那种方式会导致你的计算器的:)

Besides, if you could insert another template for current property into current template, that enables chaining any number of templates for current property, and can easily cause recursion, so one way or another it will lead you to stackoverflow :)