【问题标题】:Dynamically generated Javascript, CSS in ASP.NET MVC在 ASP.NET MVC 中动态生成 Javascript、CSS
【发布时间】:2013-04-12 03:07:00
【问题描述】:

ASP.NET 允许使用服务器标签(razor 或 ASPX)动态生成 HTML。但是除了使用内联(嵌入式)CSS / Javascript之外,有没有什么好的方法可以以相同的方式生成 *.js 或 *.css 内容。如今,随着 Ajax 等技术的出现,越来越多的逻辑在 Javascript 中从服务器端转移到客户端。如果有机会使用 ASP.NET 为 HTML 生成提供的所有灵活性来动态生成 JS,那就太好了。

例如,我的 Javascript 包含 Knockout 视图模型声明,其中包含在 Javascript 渲染期间从服务器加载的初始数据,以及一些额外的 js 函数,所以在我的 Html 中而不是嵌入式脚本 em> 我想要这样的脚本引用:

<script src="~/Scripts/ContactViewModel.js?contactId=@Model.ContactId"></script>

另一个例子,开发者可能需要它是使用基于用户配置文件的 CSS。用户配置文件信息包含在 CSS 生成期间必须遵守的样式信息(字体、颜色,而不仅仅是主题),所以在我看来,我会有类似的内容:

<link href="~/Styles/CurrentUserOverrides.css" rel="stylesheet" />

CurrentUserOverrides.css 将根据认证用户的个人资料数据动态生成。

如何使用 ASP.NET MVC 做到这一点?我想找到一个解决方案,让我能够像使用 ASP.NET 创建动态 HTML 一样简单,同时具备正常工作的智能以及 VS 为 ASP.NET 视图提供的所有其他功能。

【问题讨论】:

  • 我不确定我是否了解您想要完成的工作的好处。为什么要为特定页面生成上下文敏感的 Javascript?
  • 您是否尝试使用 ContactViewModel.js 中的contactId(并且 123 的 ContactId 实际上是由您的视图模型呈现的)?
  • 是的,ContactViewModel.js 需要用指定的 ContactId 从数据库中加载字段值来声明对象

标签: javascript asp.net css asp.net-mvc razor


【解决方案1】:

目前我找到的最佳解决方案如下:

Dynamic Javascript and CSS in ASP.NET MVC using Razor Views

您只需创建视图:CurrentUserOverrides.css.cshtml、ContactViewModel.js.cshtml。此视图将包含单个 HTML 块(&lt;script&gt;&lt;style&gt;),因此 IntelliSense 工作正常。然后您创建控制器来呈现该视图,修剪根标记并返回具有适当内容类型的内容。

【讨论】:

    【解决方案2】:

    CSHTML 文件中的动态 CSS

    我使用 CSS cmets /* */ 注释掉一个新的 &lt;style&gt; 标记,然后我在结束样式标记之前 return;

    /*<style type="text/css">/* */
    
        CSS GOES HERE
    
    @{return;}</style>
    

    CSHTML 文件中的动态 JS

    我使用 JavaScript cmets &lt;!--// 注释掉一个新的 &lt;script&gt; 标记,然后我在结束脚本标记之前 return;

    //<script type="text/javascript">
    
        JAVASCRIPT GOES HERE
    
    @{return;}</script>
    

    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>
    

    MyDynamicJavsScript.cshtml

    @{
    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>
    

    无需控制器(使用视图/共享)

    我将我的两个动态脚本都放入了Views/Shared/,我可以使用以下代码轻松地将它们嵌入到任何现有页面(或_Layout.cshtml)中:

    <style type="text/css">@Html.Partial("MyDynamicCss")</style>
    <script type="text/javascript">@Html.Partial("MyDynamicJavaScript")</script>
    

    使用控制器(可选)

    如果您愿意,可以创建一个控制器,例如

    <link rel="stylesheet" type="text/css" href="@Url.Action("MyDynamicCss", "MyDynamicCode")">
    <script type="text/javascript" src="@Url.Action("MyDynamicJavaScript", "MyDynamicCode")"></script>
    

    这是控制器的外观

    MyDynamicCodeController.cs(可选)

    [HttpGet]
    public ActionResult MyDynamicCss()
    {
        Response.ContentType = "text/css";
        return View();
    }
    
    [HttpGet]
    public ActionResult MyDynamicJavaScript()
    {
        Response.ContentType = "application/javascript";
        return View();
    }
    

    备注

    • 控制器版本未经测试。我只是在脑海中输入的。
    • 在重新阅读我的答案后,我突然想到,注释掉结束标记而不是使用 cshtml @{return;} 可能同样容易,但我还没有尝试过。我想这是一个偏好问题。
    • 关于我的整个回答,如果您发现任何语法错误或改进,请告诉我。

    【讨论】:

    • 多么棒的答案。谢谢你。正是我所需要的。我只是不明白棘手的// 部分。你能详细说明吗?
    • @RoyiNamir 自动完成和颜色。在 JavaScript 示例中,Web 浏览器正在读取 JavaScript,看到 // 并忽略该行的其余部分作为 JavaScript 注释。所以网络浏览器会忽略&lt;script&gt; 标签。不过,Visual Studio 认为所有 cshtml 文件都是 HTML。 Visual Studio 将// 读取为纯文本以发送到浏览器,但将&lt;script&gt; 标记视为JavaScript 块的开头。 &lt;script&gt; 标记之后的所有内容都被着色为 JavaScript,您应该从自动完成中获得 JavaScript 建议。
    • 顺便说一句 - 我已经设法做到了没有“返回”部分等:i.imgur.com/yxp52fL.jpg。所以我现在不明白@{return;} 部分
    • @{return;} 之后的任何内容都不会发送到浏览器。 cshtml 执行到此结束。 @{ 在 cshtml 视图中开始内联 C#。 return; 通常从方法或函数返回,但在这种情况下它从 cshtml 页面返回。 } 结束 cshtml 页面内的内联 C#。
    【解决方案3】:

    为时已晚,但仍然很有趣,这是我的解决方案: 像这样形成你的 cshtml 调用:

    <script src='@Url.Action("GetJS", "Home")'></script>
    

    创建一个像这样生成 JS 或 CSS 的控制器方法:

    public ActionResult GetJS()
    {
         byte[] jsDATA = System.Text.ASCIIEncoding.ASCII.GetBytes(mystingJS); 
         return File(jsDATA, "text/javascript");
    }
    

    【讨论】:

      【解决方案4】:

      有一种相对较新的语言TypeScript,我认为这可能是您正在寻找的 JavaScript,而不是 CSS。 Here 是一篇让其在 ASP.NET MVC4 中工作的帖子。

      【讨论】:

      • 是的,很遗憾 TypeScript 是开箱即用的解决方案,而且还不清楚 IntelliSense 如何在那里工作。
      • 在撰写本文时,TypeScript 开始成熟,VS 中的智能感知非常出色。虽然,我不确定这是否真的是用户要求的。
      猜你喜欢
      • 2011-12-29
      • 2011-03-18
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      • 2017-02-23
      相关资源
      最近更新 更多