可能从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注入攻击或运行时错误的大门。