可以从Javascript文件访问MVC ViewBag对象吗?

Abe*_*ler 59 c# asp.net-mvc jquery razor asp.net-mvc-3

是否可以从MVC应用程序中的javascript文件执行以下操作?

$(function(){
   alert(@ViewBag.someValue);
}
Run Code Online (Sandbox Code Playgroud)

目前它抛出错误:

引用未定义的XML名称@ViewBag

Eth*_*own 90

我不相信目前有任何方法可以做到这一点.Razor引擎不解析Javascript文件,只解析Razor视图.但是,您可以通过在Razor视图中设置变量来完成所需的操作:

<script>
  var someStringValue = '@(ViewBag.someStringValue)';
  var someNumericValue = @(ViewBag.someNumericValue);
</script>
<!-- "someStringValue" and "someNumericValue" will be available in script -->
<script src="js/myscript.js"></script>
Run Code Online (Sandbox Code Playgroud)

正如Joe在评论中指出的那样,如果其中有单引号,则上面的字符串值将会中断.如果你想让它完全是铁质的,你必须用转义的单引号替换所有单引号.问题在于所有突然的斜线都成了问题.例如,如果你的字符串是" foo \' bar",并且你替换了单引号,那么将会出现" foo \\' bar",你就会回到同样的问题.(这是链式编码的古老难度.)处理此问题的最佳方法是将反斜杠和引号视为特殊,并确保它们都被转义:

  @{
      var safeStringValue = ViewBag.someStringValue
          .Replace("\\", "\\\\")
          .Replace("'", "\\'");
  }
  var someStringValue = '@(safeStringValue)';
Run Code Online (Sandbox Code Playgroud)

  • 如果你的ViewBag.someStringValue中有一个引号,这不会打破js吗?我相信这样做的正确方法是使用隐藏的表单字段(如下面的答案所示) (2认同)

mat*_*mmo 28

不在JavaScript文件中,没有.
您的JavaScript文件可能包含一个类,您可以在View中实例化该类的新实例,然后您可以ViewBag在类构造函数中传递值.

或者,如果它不是类,那么您唯一的另一种选择是使用dataHTML元素中的属性,将它们分配给View中的属性并在JS文件中检索它们.

假设你有这个输入:

<input type="text" id="myInput" data-myValue="@ViewBag.MyValue" />
Run Code Online (Sandbox Code Playgroud)

然后在你的JS文件中你可以通过使用:

var myVal = $("#myInput").data("myValue");
Run Code Online (Sandbox Code Playgroud)

  • +1 - 这是最广泛接受的方法,也是我自己使用的方法 (2认同)
  • 小心地将 viewbag 数据存储在 html 元素中,这取决于您正在构建的数据类型和应用程序类型,这可能是一个严重的安全漏洞。在某些情况下,可能值得通过将一些逻辑从 javascript 移动到控制器来进行重组。(只有某些情况,就像我现在自己的情况一样!) :) 很好的答案! (2认同)

小智 13

在Html中:

<input type="hidden" id="customInput" data-value = "@ViewBag.CustomValue" />
Run Code Online (Sandbox Code Playgroud)

在脚本中:

var customVal = $("#customInput").data("value");
Run Code Online (Sandbox Code Playgroud)

  • 必须选择此答案!...投票+ (2认同)

Dav*_*vid 5

为此,您的JavaScript文件需要在服务器端进行预处理.本质上,它必须成为某种类型的ASP.NET视图script,引用该文件的标记实际上将引用一个响应该视图的控制器动作.

这听起来像是一堆你不想打开的蠕虫.

由于JavaScript是客户端的,为什么不将值设置为某个客户端元素并让JavaScript与之交互.这可能是间接的另一个步骤,但听起来比创建JavaScript视图要困难得多.

像这样的东西:

<script type="text/javascript">
    var someValue = @ViewBag.someValue
</script>
Run Code Online (Sandbox Code Playgroud)

然后外部JavaScript文件可以引用该someValue文档范围内的JavaScript变量.

甚至:

<input type="hidden" id="someValue" value="@ViewBag.someValue" />
Run Code Online (Sandbox Code Playgroud)

然后,您可以访问该隐藏的输入.

除非你想出一些非常灵巧的方法来实际使你的JavaScript文件可用作视图.这肯定是可行的,我不能轻易想到你遇到的任何问题(除了非常丑陋的视图代码,因为视图引擎会对JavaScript和什么是Razor感到非常困惑......所以期待大量<text>标记)所以,如果你找到一个光滑的方式来做这件事会非常酷,虽然对于那些需要稍后支持代码的人来说可能不直观.