Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于使用模型模板的动态编辑器_C#_Asp.net Mvc_Asp.net Mvc 3_Templates_Razor - Fatal编程技术网

C# 用于使用模型模板的动态编辑器

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。其想法是,这将为特定内容项指定合适的编辑器 我要做

该项目目前是MVC3,但如果需要,可以升级

我正在尝试为一个简单的cms改进内容编辑器。目前我们使用

@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中,可由自定义视图引擎找到。我认为你的第二个评论更重要