【问题标题】:Returning razor-parsed Javascript as a ViewResult from a controller从控制器返回剃刀解析的 Javascript 作为 ViewResult
【发布时间】:2011-03-07 13:43:20
【问题描述】:

我已经成功创建了一个 mvc/razor Web 应用程序,它返回已被 razor 解析的 css 文件。每次有背景图像时,我都有一个 razor sn-p 将 URL 前缀写入图像文件名。 CSS 现在看起来像这样:

body { background-image: url(@LookupUrl.Image("background.gif")); }

Css 文件现在可以正常工作,我已经开始尝试让 javascript .js 文件以相同的方式运行,但这些文件并没有发挥作用。

该代码与 css 代码相同,并且成功找到了 .js 文件,但 razor 似乎对其进行了不同的解析。这是一个示例js文件:

function testFunction() { alert('test function hit!'); }
testFunction();

Razor 似乎认为它应该编译它的代码,并给出错误:

Compiler Error Message: JS1135: Variable 'alert' has not been declared

    > Source Error:
    > 
    > Line 1:  function testFunction() {
    > Line 2:      alert('test function
    > hit!'); Line 3:  } Line 4: 
    > testFunction();

将同一文件重命名为 .css 后,它工作正常。

有没有办法让 razor 以与 .css 相同的方式处理 .js 文件?

以下是我为 razor 注册文件处理程序的方法:

RazorCodeLanguage.Languages.Add("js", new CSharpRazorCodeLanguage());
RazorCodeLanguage.Languages.Add("css", new CSharpRazorCodeLanguage());

WebPageHttpHandler.RegisterExtension(".js");
WebPageHttpHandler.RegisterExtension(".css");

构建提供程序通过 his blog post 中 Haacked 概述的方法在 PreApplicationStart 中注册。

我是否需要删除 mvc 为 .js 文件添加的处理程序?

更新 2 天

虽然我按照自己的意愿工作,但我不会向其他人推荐这种方法。在不使用 的情况下使用 Razor 解析 css/javascript 是有缺陷的 - 使用 @& 符号的 razor 的简单性将其搞砸了。考虑 CSS3 @font-face。 Razor 击中 @ 并认为它应该将其用作函数。同样的事情也可能发生在 javascript 上,并且发生在 Jquery 1.5.1 上。

相反,我可能会回到用于动态 css/javascript 的 aspx 网络表单,其中 代码块自然出现的可能性较小。

【问题讨论】:

  • 我已经能够在视图本身上使用

标签: asp.net asp.net-mvc-3 razor


【解决方案1】:

我不明白为什么 CSS 起作用而 JS 不起作用,尤其是在复制+粘贴的 JS 代码在 CSS 文件中起作用之后。

我使用 Visual Studio 中 System.Web.WebPages.Razor 源的查找/替换对话框在项目中搜索字符串“.js”。那里没有任何帮助,所以我去了 System.Web.WebPages 项目。它在 System.Web.WebPages.Util 中找到了匹配项,这是一个带有一些辅助方法的静态类。

其中一种方法是“EnsureValidPageType”,其中有一个 try/catch 块。 'catch' 块内有一条注释:

// If the path uses an extension registered with codedom, such as Foo.js,
// then an unfriendly compilation error might get thrown by the underlying compiler.
// Check if this is the case and throw a simpler error.

这让我相信 .js 有一些特殊的内置处理程序。

我搜索了一下,找不到任何东西,然后查看了 \Windows\Microsoft.NET\Framework64{version}\Config 中的 web.config。

其中有一个 buildProvider 将扩展名 .js 映射到

System.Web.Compilation.ForceCopyBuildProvider

在网站的 web.config 中删除此 buildprovider 后,.js 文件将被编译并正常工作!

我仍然不太确定 ForceCopyBuildProvider 的用途或用途,但我想知道它是否适用于 Visual Studio。各种扩展注册了不同的复制/忽略构建提供程序。

再次为回答我自己的问题而道歉,但我希望全面(华夫饼)的答案可以帮助其他人。

【讨论】:

    【解决方案2】:

    您可以尝试使用特殊的<text> 节点来指示 Razor 解析器按字面意思处理内容:

    <text>
        function testFunction() { alert('test function hit!'); }
        testFunction();
    </text>
    

    【讨论】:

    • 我猜 OP 希望能够在他的 javascript 中使用像 @LookupUrl.Image("background.gif") 这样的东西。这不适用于它周围的 标签,不是吗?
    • @fretje 应该没问题,因为解析器不会切换到代码模式,除非它遇到不属于电子邮件地址的@。如果这不起作用,更糟糕的情况是:&lt;text&gt;function doSomething(&lt;/text&gt;@Model.Param&lt;text&gt;)&lt;/text&gt;,我们都同意这是非常可怕的。
    • 我宁愿避免使用 标签,因为它们每次都会增加额外的工作来记住它们。另外,让我感到困惑的是,如果我将 javascript 文件的内容复制并粘贴到 css 文件中,它会被解析并完全按照我想要的方式返回,而不会出现任何错误。我认为在框架中的某个地方有一些东西导致 .js 的处理方式不同。
    【解决方案3】:

    默认的 Razor 解析器使用 HtmlMarkupParser 来处理模板的标记组件。目前没有任何替代解析器支持其他标记语言(您需要将 javascript 代码语言视为)。如果您确实创建了一个新的标记解析器,我想将代码和标记(即 C# 和 Javascript)分开会非常困难。

    您可以做的是使用 &lt;text&gt;&lt;/text&gt; 包装元素来强制解析器在到达模板的该部分时切换到标记模式,例如

    <text>function testFunction() { alert('test function hit!'); }</text>
    

    它不漂亮,但它应该可以解决问题。

    【讨论】:

    • 干杯马修,你和达林都在同样的 3 分钟内做出了回应,我对达林的回应发表了评论,这同样适用于这里
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    相关资源
    最近更新 更多