C# 用于使用模型模板的动态编辑器
该项目目前是MVC3,但如果需要,可以升级 我正在尝试为一个简单的cms改进内容编辑器。目前我们使用C# 用于使用模型模板的动态编辑器,c#,asp.net-mvc,asp.net-mvc-3,templates,razor,C#,Asp.net Mvc,Asp.net Mvc 3,Templates,Razor,该项目目前是MVC3,但如果需要,可以升级 我正在尝试为一个简单的cms改进内容编辑器。目前我们使用 @Html.EditorFor(model=>model.Content) //Content is a List<EditableContent> @Html.EditorFor(model=>model.Content)//内容是一个列表 EditableContent的(全新)属性为string EditorView。其想法是,这将为特定内容项指定合适的编辑器 我要做
@Html.EditorFor(model=>model.Content) //Content is a List<EditableContent>
@Html.EditorFor(model=>model.Content)//内容是一个列表
EditableContent的(全新)属性为string EditorView。其想法是,这将为特定内容项指定合适的编辑器
我要做的是,如果EditorView为null,则使用默认的EditableContent模板,否则使用EditorView作为命名模板。我知道EditorFor的重载需要一个模板,但对于每一项内容都将使用相同的模板,但这不是我想要的
我试过使用默认模板,基本上
//Shared/EditorTemplates/EditableContent.cshtml
@model Website.Areas.Admin.EditableContent
@if (!string.IsNullOrWhiteSpace(Model.EditorView))
{
<text>
@Model.EditorView
@Html.EditorForModel(Model.EditorView)
</text>
}
else
{
//Original template
}
//共享/EditorTemplates/EditableContent.cshtml
@模型Website.Areas.Admin.EditableContent
@如果(!string.IsNullOrWhiteSpace(Model.EditorView))
{
@Model.EditorView
@EditorForModel(Model.EditorView)
}
其他的
{
//原始模板
}
奇怪的是,在这种情况下,视图被定位(我有一个稍微定制的视图引擎,它似乎能够正确地定位视图)。视图的名称(通过@Model.EditorView)被发送到页面,但是@Html.EditorForModel()不会生成任何内容
您知道如何使用EditorFor或类似工具为每个项目使用自定义模板吗?您试图从已覆盖模板的视图中覆盖编辑器模板,这似乎很奇怪。我不确定这是否有效(可能,但我从未尝试过,所以我不知道)。我已经在上面的问题中添加了一些评论 如果试图从EditorTemplates文件夹中指定模板不起作用(这是可以理解的),我认为可以通过引入自定义的
EditorForModel()
override来实现。您可以使用David Ebbo的Razor Generator VS扩展来定义一个可在整个项目中使用的Razor助手
/// /Views/Helpers/AndiEditorForExtensions.cshtml
@helper AndiEditorFor(HtmlHelper html, Website.Areas.Admin.EditableContent model) {
if (!string.IsNullOrWhiteSpace(Model.EditorView)) {
<text>
@Model.EditorView
@Html.EditorForModel(Model.EditorView)
</text>
}
else {
// Call @Html.EditorFor(), which will use the default editor template (i.e., NOT your custom one defined in the database)
@Html.EditorFor(model)
}
}
更新:
更好的选择可能是完全跳过剃须刀生成器。只需定义一个定制的HtmlHelper,模仿。添加类似的if/else来处理Model.EditorView是否有值 您试图从一个已经覆盖了编辑器模板的视图中覆盖编辑器模板,这似乎很奇怪。我不确定这是否有效(可能,但我从未尝试过,所以我不知道)。我已经在上面的问题中添加了一些评论 如果试图从EditorTemplates文件夹中指定模板不起作用(这是可以理解的),我认为可以通过引入自定义的
EditorForModel()
override来实现。您可以使用David Ebbo的Razor Generator VS扩展来定义一个可在整个项目中使用的Razor助手
/// /Views/Helpers/AndiEditorForExtensions.cshtml
@helper AndiEditorFor(HtmlHelper html, Website.Areas.Admin.EditableContent model) {
if (!string.IsNullOrWhiteSpace(Model.EditorView)) {
<text>
@Model.EditorView
@Html.EditorForModel(Model.EditorView)
</text>
}
else {
// Call @Html.EditorFor(), which will use the default editor template (i.e., NOT your custom one defined in the database)
@Html.EditorFor(model)
}
}
更新:
更好的选择可能是完全跳过剃须刀生成器。只需定义一个定制的HtmlHelper,模仿。添加类似的if/else来处理Model.EditorView是否有值 接口
interface IEditableContent
{
public virtual DatabaseContext.Content Content { get; set; }
}
实施
class SomeTypeEditableContent : IEditableContent
{
public SomeTypeEditableContent(DatabaseContext.Content c)
{
Content = c;
}
}
服务(存储库或控制器操作)
默认可编辑内容模板
@model IEditableContent
//Use default display
很抱歉,我没有时间测试它。让我知道它是如何进行的,如果没有,我将编辑/删除此答案。我本想把这篇文章作为一条评论发表,但我需要涂鸦和整理。但至少它让你了解了我的想法 -编辑- 本示例的重点是向您展示,MVC框架应该能够为实现的接口确定适当的模板,即使只是提供类型化为接口的对象。它将使用refelction(我相信?)找到最高的类定义,然后查找模板 -编辑2(基于评论)- 更改示例以匹配新的规范接口
interface IEditableContent
{
public virtual DatabaseContext.Content Content { get; set; }
}
实施
class SomeTypeEditableContent : IEditableContent
{
public SomeTypeEditableContent(DatabaseContext.Content c)
{
Content = c;
}
}
服务(存储库或控制器操作)
默认可编辑内容模板
@model IEditableContent
//Use default display
很抱歉,我没有时间测试它。让我知道它是如何进行的,如果没有,我将编辑/删除此答案。我本想把这篇文章作为一条评论发表,但我需要涂鸦和整理。但至少它让你了解了我的想法 -编辑- 本示例的重点是向您展示,MVC框架应该能够为实现的接口确定适当的模板,即使只是提供类型化为接口的对象。它将使用refelction(我相信?)找到最高的类定义,然后查找模板 -编辑2(基于评论)-
更改了示例以匹配新规范我觉得您试图绕过一些本应在MVC框架中很好实现的内容。你到底想在更高的层次上实现什么?也许我们可以引导你朝着正确的方向前进,而不是帮助你完成这项工作?(或者我偏离了轨道,您所做的是正确的!:D)在您的测试用例中,Model.EditorView中引用的视图的完整路径是什么?EditorForModel(字符串)在控制器的编辑器模板文件夹中查找,然后在“Views\Shared\EditorTemplates”中查找,如果在这些位置中找不到,则使用默认模板。此外,由于您已经从deafault模板调用EditorForModel,我不确定MVC在尝试查找默认模板时会有什么表现。或者,如果它甚至会尝试查找并使用指定的模板,假设它位于上面提到的搜索路径之一。@pluc我正试图针对集合包含不同的editorfor模板(以便集合中的每个项目呈现的实际模板可能不同,这取决于该项目中的数据),我的黑客行为非常可怕,但我相信它不包括在framework@GiscardBiamby模板位于某个区域中,但位于Views\SharedEditor Templates中,可由自定义视图引擎找到。我认为你的第二个评论更重要