ASP.NET MVC的HtmlHelper类用来在网页中生成html脚本,这里有几个扩展方法,几乎每个ASP.NET MVC或ASP.NET MVC Core项目都可以用到,在这里记一下,免得每次都去翻以前的项目。
/// <summary>
/// 为Html类添加的扩展方法
/// </summary>
public static class HtmlExtensions
{
/// <summary>
/// 在子视图中呈现一段脚本,用于编辑模板等不能使用@section嵌入脚本的视图
/// <para>用法:@Html.Script(@<script>脚本内容</script>)</para>
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="template"></param>
/// <returns></returns>
public static string Script(this IHtmlHelper htmlHelper, Func<object, HelperResult> template)
{
htmlHelper.ViewContext.HttpContext.Items["_script_" + Guid.NewGuid()] = template;
return string.Empty;
}
/// <summary>
/// 呈现<see cref="Script(HtmlHelper, int, Func{object, HelperResult})"/>嵌入的脚本
/// </summary>
/// <param name="htmlHelper"></param>
/// <returns></returns>
public static string RenderScripts(this IHtmlHelper htmlHelper)
{
foreach (object key in htmlHelper.ViewContext.HttpContext.Items.Keys)
{
if (key.ToString().StartsWith("_script_"))
{
var template = htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>;
if (template != null)
{
htmlHelper.ViewContext.Writer.Write(template(null));
}
}
}
return string.Empty;
}
/// <summary>
/// 在网页中生成引入js文件的<script src=></script>代码
/// </summary>
/// <param name="htmlHelper"></param>
/// <param name="action">动作方法名称,默认为当前动作方法</param>
/// <param name="controller">控制器名称,默认为当前控制器</param>
/// <param name="root">js文件的根目录,默认为"~/js/"</param>
/// <returns><script> src="{root}{controller.ToLower()}.{action.ToLower()}.js"</script></returns>
public static HtmlString LoadScriptFile(this IHtmlHelper htmlHelper, string action = null, string controller = null, string root = "/js/")
{
if (action == null)
{
action = (htmlHelper.ViewContext.ActionDescriptor as ControllerActionDescriptor).ActionName;
}
if (controller == null)
{
controller = (htmlHelper.ViewContext.ActionDescriptor as ControllerActionDescriptor).ControllerName;
}
//AddPathSeparator(),字符串扩展方法,检查字符串是否以"\"结束,不是则加上"\"
root = root.AddPathSeparator();
var fileName = $"{root}{controller.ToLower()}.{action.ToLower()}.js";
#if DEBUG
string localPath = Directory.GetParent(AppContext.BaseDirectory).Parent.Parent.Parent.FullName.AddPathSeparator();
#else
string localPath = AppContext.BaseDirectory.AddPathSeparator();
#endif
var localFile = $"{localPath}wwwroot{fileName}";
if (File.Exists(localFile))
{
return new HtmlString($"<script src=\"{root}{controller.ToLower()}.{action.ToLower()}.js?v={File.GetLastWriteTime(localFile).Ticks}\"></script>");
}
return null;
}
}
一般情况下,我们可以在_Layout.cshtml中使用@RenderSection("Scripts", required: false)
来嵌入脚本。
例如_Layout.cshtml的代码如下:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
@RenderBody()
<script src="~/lib/jquery/jquery.min.js"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
视图代码如下:
<div>
页面内容
</div>
@section scripts{
<script>
$(function () {
})
</script>
}
最后生成的网页就是下面这样:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
页面内容
</div>
<script src="~/lib/jquery/jquery.min.js"></script>
<script>
$(function () {
})
</script>
</body>
</html>
但是如果我在编辑模板中嵌入了js脚本,页面又引用了编辑模板,那么编辑模板中的脚本不会被RenderSection方法呈现出来。
例如:
编辑模板.cshtml:
<div>
页面内容
</div>
@section scripts{
<script>
$(function () {
})
</script>
}
内容视图:
<form asp-action="Create" data-ajax="true" data-ajax-success="onSuccess">
@Html.EditorForModel("编辑模板")
</form>
生成的页面:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
页面内容
</div>
<script src="~/lib/jquery/jquery.min.js"></script>
<!--这里应该有的脚本没有出现-->
</body>
</html>
我写的扩展方法Script和RenderScripts就是用来解决这个问题的。
在编辑模板中用Script方法嵌入脚本
<div>
页面内容
</div>
@Html.Script(
@<script>
$(function () {
})
</script>
)
在_Layout.cshtml中用RenderScipts来呈现脚本
<!DOCTYPE html>
<html>
<head>
</head>
<body>
@RenderBody()
<script src="~/lib/jquery/jquery.min.js"></script>
@RenderSection("Scripts", required: false)
@*呈现编辑模板中的脚本*@
@Html.RenderScipts()
</body>
</html>
第三个方法LoadScriptFile方法用来加载当前网页对应的js脚本文件。如果一个页面上含有大量的js代码,我们通常都会把这些代码放到独立的js文件中,这个方法就是用来自动加载这些独立的js脚本的。
使用方式很简单,在_Layout.cshtml中需要加载脚本的地方插入@Html.LoadScriptFile()
,然后把脚本文件命名为控制器名称.动作方法名称.js
,并放到指定目录下就可以了。
例如HomeController中的Index的脚本文件,命名就是home.index.js
,默认目录是网站根路径下的js目录,本文中的代码对应的是ASP.NET MVC Core版本,默认目录是网站根路径下wwwrooot下的js目录。
方法会自动检测脚本文件是否存在,存在则会生成<script src="文件路径"></script>
代码加载脚本文件。
方法也可以指定参数:@Html.LoadScriptFile("Create","User","/scripts")
加载wwwroot/scripts目录下的user.create.js脚本文件。
网友评论