可能从JavaScript文件访问MVC ViewBag对象?

是否有可能从一个MVC应用程序中的JavaScript文件做到以下几点?

$(function(){ alert(@ViewBag.someValue); } 

目前它抛出的错误:

引用未定义的XML名称@ViewBag

我不相信现在有什么办法可以做到这一点。 Razor引擎不parsingJavaScript文件,只parsingRazor视图。 但是,您可以通过在Razor视图中设置variables来完成您想要的操作:

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

正如Joe在评论中所指出的那样,如果有一个单引号,那么上面的string值就会中断。 如果你想完全熨平,你将不得不用单引号replace所有的单引号。 问题在于所有突然的斜线成为一个问题。 例如,如果你的string是“ foo \' bar ”,并且你replace了单引号,那么会出现什么是“ foo \\' bar ”,你又回到了同样的问题。 (这是链接编码的古老难度)处理这个问题的最佳方法是将反斜杠和引号作为特殊处理,并确保它们全部被转义:

  @{ var safeStringValue = ViewBag.someStringValue .Replace("\\", "\\\\") .Replace("'", "\\'"); } var someStringValue = '@(safeStringValue)'; 

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

或者,如果它不是一个类,唯一的select是在HTML元素中使用data属性,将它们分配给View中的属性,并在JS文件中检索它们。

假设你有这个input:

 <input type="text" id="myInput" data-myValue="@ViewBag.MyValue" /> 

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

 var myVal = $("#myInput").data("myValue"); 

为了做到这一点,您的JavaScript文件需要在服务器端进行预处理。 从本质上讲,它必须成为某种ASP.NET视图,引用该文件的script标记实质上是引用了一个控制器操作,该操作响应该视图。

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

由于JavaScript是客户端,为什么不把它设置为某个客户端元素,并让JavaScript与之交互。 这可能是一个间接的额外步骤,但听起来不像创build一个JavaScript视图那么麻烦。

像这样的东西:

 <script type="text/javascript"> var someValue = @ViewBag.someValue </script> 

然后,外部JavaScript文件可以引用该文档范围内的someValue JavaScriptvariables。

甚至:

 <input type="hidden" id="someValue" value="@ViewBag.someValue" /> 

然后你可以访问那个隐藏的input。

除非你想出了一些非常stream畅的方法来使你的JavaScript文件可以用作视图。 这当然是可行的,我不能轻易想到任何问题(除了真正丑陋的视图代码,因为视图引擎会非常困惑,什么是JavaScript和什么是Razor …所以期待一大堆 <text>标记),所以如果你find了一个爽快的方法来做到这一点,这将是非常酷的,尽pipe以后需要支持代码的人可能是不直观的。

在Html中:

 <input type="hidden" id="customInput" data-value = "@ViewBag.CustomValue" /> 

在脚本中:

 var customVal = $("#customInput").data("value"); 

在.cshtml文件中使用此代码。

  @{ var jss = new System.Web.Script.Serialization.JavaScriptSerializer(); var val = jss.Serialize(ViewBag.somevalue); } <script> $(function () { var val = '@Html.Raw(val)'; var obj = $.parseJSON(val); console.log(0bj); }); </script> 

创build一个视图并将其作为局部视图返回:

 public class AssetsController : Controller { protected void SetMIME(string mimeType) { this.Response.AddHeader("Content-Type", mimeType); this.Response.ContentType = mimeType; } // this will render a view as a Javascript file public ActionResult GlobalJS() { this.SetMIME("text/javascript"); return PartialView(); } } 

然后在GlobalJS视图中添加javascript代码(添加//将使Visual Studio intellisense将其读为java脚本)

 //<script> $(document).ready(function () { alert('@ViewBag.PropertyName'); }); //</script> 

然后在你最后的视图中,你可以像这样添加一个对JavaScript的引用。

 <script src="@Url.Action("GlobalJS", "Assets")"></script> 

然后在你的最终视图控制器中,你可以创build/传递你的ViewBag,它将会呈现在你的javascript中。

 public class MyFinalViewController : Controller { public ActionResult Index() { ViewBag.PropertyName = "My ViewBag value!"; return View(); } } 

希望能帮助到你。

在控制器操作中添加:

  public ActionResult Index() { try { int a, b, c; a = 2; b = 2; c = a / b; ViewBag.ShowMessage = false; } catch (Exception e) { ViewBag.ShowMessage = true; ViewBag.data = e.Message.ToString(); } return View(); // return View(); } in Index.cshtml Place at the bottom: <input type="hidden" value="@ViewBag.data" id="hdnFlag" /> @if (ViewBag.ShowMessage) { <script type="text/javascript"> var h1 = document.getElementById('hdnFlag'); alert(h1.value); </script> <div class="message-box">Some Message here</div> } 

我注意到,如果您尝试这样做,Visual Studio的内置错误检测器会变得愚蠢:

 var intvar = @(ViewBag.someNumericValue); 

由于@(ViewBag.someNumericValue)有可能计算为空,这将导致以下错误的JavaScript生成:

 var intvar = ; 

如果您确定someNemericValue将被设置为有效的数字数据types,则可以通过执行以下操作来避免出现Visual Studio警告:

 var intvar = Number(@(ViewBag.someNumericValue)); 

这可能会生成以下示例:

 var intvar = Number(25.4); 

它适用于负数。 如果该项目不在您的viewbag中,Number()的计算结果为0。

没有更多的Visual Studio警告! 但是请确保该值已设置,并且是数字,否则您打开可能的JavaScript注入攻击或运行时错误的大门。