将服务器端转换为Razor

Bro*_*oam 5 asp.net-mvc razor

我正在将ASP.NET webforms应用程序升级/修改为MVC5 - 理想情况下是Razor引擎(允许自动移动布局页面切换,并利用MVC功能).

我们有数百个服务器端包含,全部命名为*.inc.他们的绝对gobs.应用程序非常庞大,以至于我们必须逐页转换页面 - 没有办法一次完成所有操作.(为了了解这个项目有多大以及它有多长,我们迁移到TFS时VSS中的整个源代码控制历史大约是10GB.这包括很多媒体文件,但仍然.它很大,而且它不会远.)

有没有什么方法可以转换这些#!include调用RenderPartial()或RenderAction()调用而不将每个文件重命名为.cshtml?

复制包含文件是一个糟糕的建议,因为这会打破DRY.

理想情况下,我想要一个处理这个问题的局部视图 - 我想它会把文件名作为一个参数,而且它是一个单行的东西,所以我可以训练每个人将这些文件简单地转换.

我还想要一些文件级缓存.只是从磁盘加载输出并将其转储到输出流中对于小型站点来说很有用......但这不是一个小站点.

我们有一个ascx文件,它现在为许多这些包括缓存 - 但我不知道如何在Razor中编写相应的.

编辑1:这些大部分都是非代码包含的,但我确信用户控件定义已经悄悄进入了一些.我必须重写那些,所以假设答案是"这些是纯HTML,没有代码"

编辑2:我们有嵌套包含文件的情况(我发誓不是我).包含文件可以包含其他文件.我有一个缓存ASCX控件,递归处理这个,所以这是移植代码的问题.

编辑3:任何可能的解决方案也必须适用于布局cshtml文件.我们已经包含在现有的母版页中.

Bre*_*ing 6

在我的头脑中,我可以想到解决这个问题的4种方法.

注意:我对缓存机制没有太多麻烦,因为这个设计决定超出了这个问题.


创建一个控制器/动作来为您呈现包含:

public class IncludeController : Controller
{
    // GET: Render
    public ActionResult Render(string path)
    {
        return new IncludeResult(path);
    }
}

public class IncludeResult : ActionResult
{
    private string _path { get; set; }

    public IncludeResult(string path)
    {
        _path = path;
    }
    public override void ExecuteResult(ControllerContext context)
    {
        // possibly check the cache here, or let MVC handle cache at the action level
        // get the contents of the include file output to the response
        context.HttpContext.Response.Write(File.OpenRead(_path));
    }
}
Run Code Online (Sandbox Code Playgroud)

在视图中

@Html.Action("Render", "Include", new {path = "~/Includes/test.inc"})
Run Code Online (Sandbox Code Playgroud)

注意:尝试使用FilePathResult,它似乎返回奇数字符,因此自定义 IncludeResult


创建一个HtmlHelper扩展:

public static class HtmlExtension
{
    public static MvcHtmlString RenderInclude(this HtmlHelper helper, string path)
    {
        // check the cache
        string output = File.ReadAllText(path);
        return new MvcHtmlString(output);
    }
}
Run Code Online (Sandbox Code Playgroud)

在视图中

@Html.RenderInclude("~/includes/test.inc")
Run Code Online (Sandbox Code Playgroud)

我认为这个选项适合你想要做的最好但是从最纯粹的方法,这可能不适合'MVC做事的方式'


扩展RazorViewEngine以查找包含文件:

我没有探索到这一点,并且可能对你想要实现的目标有点过分,但是下面的博客有一些代码示例可以帮助你:http://weblogs.asp.net/imranbaloch/view-发动机与-动态-视图-位置

然后,您可以Html.Partial在视图中使用标准代码

@Html.Patial("~/includes/test.inc");
Run Code Online (Sandbox Code Playgroud)

将包含内容公开在视图模型的属性中:

这似乎是最麻烦的,但仍然是一种选择.

public class ViewModel
{
    public MvcHtmlString IncludeContents { get; set; }
    ....

    private GetIncludeContent(string path)
    {
        IncludeContents = new MvcHtmlString(File.ReadAllText(path));
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在视图中

@model.IncludeContents
Run Code Online (Sandbox Code Playgroud)