使用Asp.Net Mvc以编程方式在内容页面中定义节名称

时间:2015-01-23 16:02:24

标签: c# asp.net-mvc

我不是在谈论RenderSection,我的问题与布局页面无直接关系。

首先,我想告诉你我想做什么。我有一个

public class Module
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int Ordering { get; set; }
    public string Position { get; set; }
    public bool Published { get; set; }
    public string ModulePath { get; set; }
    public bool ShowTitle { get; set; }
}

表名为Module。模块就像小部件。请注意Position和ModulePath字段。

位置类似于布局页面中定义的ContentPlaceHolder。在Mvc中我定义如下的位置。

RenderSection("PositionName", required:false)

ModulePath字段包含PartialView的位置。它们将以布局呈现。

问题从这里开始。如何以编程方式执行此操作。

通常我们使用;

@section PositionName
{
   @html.Partial(...)
}

在内容页面中定义一个部分。

在Asp.net WebForms中,这很容易做到。

ContentPlaceHolder.FindControl(PositionName).Controls.Add(..)

我需要以编程方式指定部分名称,这是在内容页面中

其实我需要这样的东西;

foreach(var item in Model.Modules)
{
   this.AddSection(item.Position, item.ModulePath, item.Ordering)
}

手动方式

@section PositionName
{
    @html.Partial("~/Views/Shared/AModule.cshtml")
    @html.Partial("~/Views/Shared/AnotherModule.cshtml")
    @html.Partial("~/Views/Shared/AnotherModule.cshtml")
}

我试过了;

@section @SectionName
{
   ...
}

ofcource失败了。

所以最好将PartialViews动态放置在管理面板上设置位置的页面的任何位置。这就是我想要做的事情。

3 个答案:

答案 0 :(得分:1)

根据我的知识,在ASP.NET MVC中没有选择这样做,但它应该是可行的。

当页面呈现为HTML时,它们会被添加到ViewContext对象中,所以我想你想要用渲染的视图替换HTML的区域。您可以像以下那样访问当前呈现的HTML:

var htmlContent = string.Empty;
var view = ViewEngines.Engines.FindView(ControllerContext, relativePath, null);
using (var writer = new StringWriter())
{
    var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
    view.View.Render(context, writer);
    writer.Flush();
    htmlContent = writer.ToString();
}

考虑到这一点,您可以使用某种可以匹配的标记以编程方式替换字符串的区域。

答案 1 :(得分:0)

无法动态添加部分,但您可以在现有部分中动态呈现。例如:

@section FooPosition
{
    foreach (var module in models.Where(m => m.Position == "FooPosition"))
    {
        @Html.Partial(...);
    }
}

换句话说,您定义可用位置的部分,然后允许模块只有一个可用的位置。然后,您只需渲染该部分内属于该位置的任何模块。

答案 2 :(得分:0)

您可以像这样以编程方式定义一个部分:

DefineSection("YoursectionName", async (a) =>
{

     this.Write(await this.Component.InvokeAsync(widget.Name, widget.Parameters));

});

基本上,您将对所有部分进行Select并通过调用给定组件然后编写结果HTML来为每个部分定义该部分。