【问题标题】:HtmlHelper implementation MVC 6 vNextHtmlHelper 实现 MVC 6 vNext
【发布时间】:2015-12-02 18:52:23
【问题描述】:

我正在使用 ASP.NET 5 / MVC 6。我在部分页面内使用自定义 HtmlHelper 向 HttpContext 注册脚本标记,以便我可以延迟渲染脚本标记直到页面结束.

这段代码注册了脚本标签:

    public static HtmlString AddResource(this IHtmlHelper HtmlHelper, PageResourceType resourceType, Func<object, HelperResult> Template)
    {     
            if (HtmlHelper.ViewContext.HttpContext.Items[resourceType] != null)
            {
                ((List<Func<object, HelperResult>>)HtmlHelper.ViewContext.HttpContext.Items[resourceType]).Add(Template);
            }
            else
            {
                HtmlHelper.ViewContext.HttpContext.Items[resourceType] = new List<Func<object, HelperResult>>() { Template };
            }

           return new HtmlString(String.Empty);
    }

使用此帮助程序从 Razor 页面注册脚本标签的用法是

 @Html.AddResource(PageResourceType.JavaScript ,
                    @<script src='~/js/plugin/sparkline/jquery.sparkline.js'></script>
                    )

此代码从 _Layout.cshtml 调用,呈现任何已注册的脚本标签:

    public static HtmlString RenderResources(this IHtmlHelper HtmlHelper, PageResourceType resourceType)
    {
        if (HtmlHelper.ViewContext.HttpContext.Items[resourceType] != null)
        {
            List<Func<object, HelperResult>> Resources = (List<Func<object, HelperResult>>)HtmlHelper.ViewContext.HttpContext.Items[resourceType];

            foreach (var Resource in Resources)
            {
                if (Resource != null)
                {
                    HtmlHelper.ViewContext.Writer.Write(Resource(null));
                }
            }
        }

        return new HtmlString(String.Empty);
    }

这两位工作得很好,但是,我现在有一个额外的 HtmlHelper,我想用它来创建依赖于脚本标签的特定 UI 元素(在本例中为 Sparkline UI 小部件)。

    public static HtmlString Sparkline(this IHtmlHelper HtmlHelper, IEnumerable<int> values, string cssClasses)
    {            
        StringBuilder sb = new StringBuilder();
        sb.Append("<div class='sparkline txt-color-blue hidden-mobile hidden-md hidden-sm'>");
        sb.Append(string.Join(",", values));
        sb.Append("</div>");

        HtmlHelper.AddResource(PageResourceType.JavaScript, (x) =>
        {
            return new HelperResult(writer =>
            {
                string script = "<script src='~/js/plugin/sparkline/jquery.sparkline.js'></script>";
                return new Task(() => writer.Write(script));
            });
        });

        return new HtmlString(sb.ToString());
    }

注意,它调用了之前的注册方法

HtmlHelper.AddResource

问题是当 RenderResources 代码执行时,应用程序只是无限期地挂起。我在旧的 MVC 5 系统下工作,但必须进行一些更改以考虑新的 MVC 6 构造(我认为是标签助手导致了更改),但不知何故我搞砸了。

知道如何正确实现 Sparkline 方法,尤其是对 HtmlHelper.AddResource 的调用吗?

TIA!

【问题讨论】:

    标签: asp.net-mvc razor asp.net-core asp.net-core-mvc tag-helpers


    【解决方案1】:

    当然,我发布问题的那一刻,我就找到了答案。虽然,我不确定为什么它可以解决问题,因为我认为将 .Write 方法包装在 Task 中与调用 .WriteAsync ...

        HtmlHelper.AddResource(PageResourceType.JavaScript, (x) =>
        {
            return new HelperResult(writer =>
            {
                string script = "<script src='~/js/plugin/sparkline/jquery.sparkline.js'></script>";
                return new Task(() => writer.Write(script));
            });
        });
    

    应该是

        HtmlHelper.AddResource(PageResourceType.JavaScript, (x) =>
        {
            return new HelperResult(writer =>
            {
                string script = "<script src='~/js/plugin/sparkline/jquery.sparkline.js'></script>";
                return writer.WriteAsync(script);
            });
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-01
      • 1970-01-01
      • 2015-05-20
      • 1970-01-01
      相关资源
      最近更新 更多