在ASP.NET MVC Razor视图中转换@helper的输出

时间:2012-09-09 10:30:33

标签: asp.net-mvc razor view-helpers

是否可以在@helper的输出上实现自定义转换?我的意思是找到一个解决方案,让我能够有这样的方法:

@helper RenderCombinedStylesheetsWithColorOverride(string color)
{
    <link rel="stylesheet" type="text/css" href="menu.css" />
    <link rel="stylesheet" type="text/css" href="site.css" />
    <style type="text/css">
        * { color: @color; }
    </style>
}

扭曲是以帮助者的名义(RenderCombinedStylesheets ...),暗示了我想在这里做的事情。也就是说,获取帮助程序的正常HTML编码输出,并通过我的自定义代码进行管道传输。在那里,我想将它拆开然后重新组合,以便最终输出是对生成的组合和缩小的css文件的单个<link rel="stylesheet" ... />引用。

请注意,这是一个简化的示例!实际上,有多个参数,输出转换不​​仅限于组合样式表片段。我也想以这种方式生成JavaScript代码。

主要目标是提出一些能够让我将常规Razor模板应用于我的视图的特定部分然后再对这些部分执行其他转换的内容发出最终结果。

任何想法都赞赏!

更新:我偶然发现了this这个问题,这表明实现这一目标的方法是通过简单的'HtmlHelper扩展。我似乎对他们的所作所为一直不完全了解,或者至少低估了他们的权力。我将报告实施情况。

1 个答案:

答案 0 :(得分:0)

是的!我在更新的问题中链接的帖子是现货!这是解决方案:

public static class ResourceCombiningHelper
{
    private static string MakeKey(string type)
    {
        return "CombinableResource" + (type ?? "").ToLowerInvariant();
    }

    public static IHtmlString CombinableResource(this HtmlHelper helper, dynamic template, string type)
    {
        var key = MakeKey(type);
        var context = helper.ViewContext.HttpContext;
        var resources = (List<dynamic>)context.Items[key];

        if (resources == null)
        {
            resources = new List<dynamic> { template };
            context.Items[key] = resources;
        }
        else
        {
            resources.Add(template);
        }

        return new HtmlString(String.Empty);
    }

    public static IHtmlString RenderCombinableResources(this HtmlHelper helper, string type)
    {
        var key = MakeKey(type);
        var context = helper.ViewContext.HttpContext;
        var resources = (List<dynamic>)context.Items[key];

        if (resources != null)
        {
            foreach (var resource in resources)
            {
                if (resource is HelperResult)
                {
                    // Add in-line content to combined resource here.
                }
                else if (resource is string)
                {
                    // Add external reference to combined resource here.
                }
            }
        }

        // Return a single reference to the combined resource (<link>, <script>, etc.)
    }
}

Razor视图中的用法:

@helper ColorOverridingStyle(string color)
{
    <style type="text/css">
        * { color: @color; }
    </style>
}

@{ var color = ViewBag.TextColor; }
@Html.CombinableResource(Url.Content("~/Content/site.css"), "css")
@Html.CombinableResource(Url.Content("~/Content/menu.js"), "js")
@Html.CombinableResource(ColorOverridingStyle(color), "css")

最终的HTML输出示例:

<head>
    <link href="/Content/combined-css.css" rel="stylesheet" type="text/css" />
    <script src="/Content/combined-js.js" type="text/javascript"></script>
</head>

效果很好!关闭以扩展这个小宝石的极限...... :)