ASP.NET MVC中动态生成的Javascript、CSS
ASP.NET允许使用服务器标记(razor或ASPX)动态生成HTML。但是除了使用内联(嵌入式)css/Javascript之外,还有什么好方法可以以相同的方式生成*.js或*.css内容呢。如今,随着Ajax等技术的发展,越来越多的逻辑在Javascript中从服务器端转移到客户端。如果有机会使用ASP.NET为HTML生成提供的所有灵活性动态生成JS,那就太好了 例如,我的Javascript包含敲除视图模型声明,在Javascript呈现期间从服务器加载初始数据,以及一些附加的js函数,因此在我的Html中,而不是嵌入脚本中,我希望有这样的脚本引用:ASP.NET MVC中动态生成的Javascript、CSS,javascript,asp.net,css,asp.net-mvc,razor,Javascript,Asp.net,Css,Asp.net Mvc,Razor,ASP.NET允许使用服务器标记(razor或ASPX)动态生成HTML。但是除了使用内联(嵌入式)css/Javascript之外,还有什么好方法可以以相同的方式生成*.js或*.css内容呢。如今,随着Ajax等技术的发展,越来越多的逻辑在Javascript中从服务器端转移到客户端。如果有机会使用ASP.NET为HTML生成提供的所有灵活性动态生成JS,那就太好了 例如,我的Javascript包含敲除视图模型声明,在Javascript呈现期间从服务器加载初始数据,以及一些附加的js函数
<script src="~/Scripts/ContactViewModel.js?contactId=@Model.ContactId"></script>
<script src='@Url.Action("GetJS", "Home")'></script>
开发人员可能需要的另一个例子是使用基于用户配置文件的CSS。用户配置文件信息包含样式信息(字体、颜色,而不仅仅是主题),在CSS生成过程中必须遵守这些信息,因此在我看来,我将有如下内容:
<link href="~/Styles/CurrentUserOverrides.css" rel="stylesheet" />
CurrentUserOverrides.css将根据已验证用户的配置文件数据动态生成
如何使用ASP.NET MVC实现这一点?我想找到一个解决方案,使我能够像使用ASP.NET创建动态HTML一样轻松地完成这项工作,并具有正常工作的智能以及VS为ASP.NET视图提供的所有其他功能。到目前为止,我找到的最佳解决方案如下:
您只需创建视图:CurrentUserOverrides.css.cshtml、ContactViewModel.js.cshtml。此视图将包含单个HTML块(
或
),因此IntelliSense工作正常。然后创建一个控制器,用于呈现该视图、修剪根标记并返回具有适当内容类型的内容。我认为有一种相对较新的语言可能是JavaScript所需要的,而不是CSS。是一篇在ASP.NET MVC4中实现该功能的文章。CSHTML文件中的动态CSS
我使用CSS注释/**/
注释出一个新的
标记,然后返回代码>在结束样式标记之前:
/*<style type="text/css">/* */
CSS GOES HERE
@{return;}</style>
MyDynamicCss.cshtml
@{
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
}/*<style type="text/css">/* */
@foreach (var field in fieldList) {<text>
input[name="@field"]
, select[name="@field"]
{
background-color: #bbb;
color: #6f6f6f;
}
</text>}
@{return;}</style>
@{
var fieldList = new List<string>();
fieldList.Add("field1");
fieldList.Add("field2");
fieldArray = string.Join(",", fieldList);
}
//<script type="text/javascript">
$(document).ready(function () {
var fieldList = "@Html.Raw(fieldArray)";
var fieldArray = fieldList.split(',');
var arrayLength = fieldArray.length;
var selector = '';
for (var i = 0; i < arrayLength; i++) {
var field = fieldArray[i];
selector += (selector == '' ? '' : ',')
+ 'input[name="' + field + '"]'
+ ',select[name="' + field + '"]';
}
$(selector).attr('disabled', 'disabled');
$(selector).addClass('disabled');
});
@{return;}</script>
[HttpGet]
public ActionResult MyDynamicCss()
{
Response.ContentType = "text/css";
return View();
}
[HttpGet]
public ActionResult MyDynamicJavaScript()
{
Response.ContentType = "application/javascript";
return View();
}
使用控制器(可选)
如果您愿意,您可以创建一个控制器,例如
<link rel="stylesheet" type="text/css" href="@Url.Action("MyDynamicCss", "MyDynamicCode")">
<script type="text/javascript" src="@Url.Action("MyDynamicJavaScript", "MyDynamicCode")"></script>
注释
- 未测试控制器版本。我只是在头顶上打了下来
- 重新阅读我的答案后,我突然想到,注释掉结束标记可能比使用cshtml
更容易,但我没有尝试过。我想这是一个偏好的问题@{return;}
- 关于我的全部答案,如果您发现任何语法错误或改进,请告诉我
- 为时已晚,但仍然是一个有趣的话题,以下是我的解决方案:
按如下方式形成cshtml调用:
<script src="~/Scripts/ContactViewModel.js?contactId=@Model.ContactId"></script>
<script src='@Url.Action("GetJS", "Home")'></script>
我不确定我是否理解你试图实现的目标的好处。为什么要为特定页面生成上下文敏感的Javascript?是否尝试使用ContactViewModel.js中的contactId(并且contactId为123实际上由视图模型呈现)?是的,ContactViewModel.js需要使用指定的ContactyLeah从数据库加载的字段值声明对象,不幸的是,TypeScript是现成的解决方案,而且IntelliSense在那里的工作方式也不清楚。在撰写本文时,TypeScript已经开始成熟,并且VS中的IntelliSense非常出色。虽然,我不确定这是否真的是用户想要的。这是一个多么好的答案。非常感谢。正是我所需要的。我只是不理解这个棘手的
/
部分。你能详细说明吗?@RoyiNamir自动完成和颜色。在JavaScript示例中,web浏览器正在读取JavaScript,查看/
,并忽略作为JavaScript注释的行的其余部分。因此,web浏览器忽略了
标记。然而,VisualStudio认为所有cshtml文件都是HTML。VisualStudio将/
读取为发送到浏览器的纯文本,但将
标记视为JavaScript块的开头。
标记之后的所有内容都被着色为JavaScript,您应该从autocomplete.BTW获得JavaScript建议-我已经设法做到了,没有“return”部分等。所以我现在不明白@{return;}
部分@{return;}
之后的任何内容都不会发送到浏览器。cshtml执行到此结束@{
从cshtml视图中的内联C#开始。return;
通常从方法或函数返回,但在这种情况下,它从cshtml页面返回。}
在cshtml页面中结束内联C#。
public ActionResult GetJS()
{
byte[] jsDATA = System.Text.ASCIIEncoding.ASCII.GetBytes(mystingJS);
return File(jsDATA, "text/javascript");
}