是否可以从 MVC 应用程序中的 javascript 文件执行以下操作?
$(function(){
alert(@ViewBag.someValue);
}
目前它抛出错误:
引用未定义的 XML 名称 @ViewBag
是否可以从 MVC 应用程序中的 javascript 文件执行以下操作?
$(function(){
alert(@ViewBag.someValue);
}
目前它抛出错误:
引用未定义的 XML 名称 @ViewBag
我不相信目前有任何方法可以做到这一点。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>
正如乔在评论中指出的那样,如果上面的字符串值中有一个单引号,它就会中断。如果你想让这个完全铁定,你必须用转义的单引号替换所有的单引号。那里的问题是所有突然的斜线成为一个问题。例如,如果你的字符串是“ foo \' bar
”,并且你替换了单引号,那么会出现“ foo \\' bar
”,你又回到了同样的问题。(这是链式编码的古老难题。)处理这个问题的最佳方法是将反斜杠和引号视为特殊并确保它们都被转义:
@{
var safeStringValue = ViewBag.someStringValue
.Replace("\\", "\\\\")
.Replace("'", "\\'");
}
var someStringValue = '@(safeStringValue)';
不在 JavaScript 文件中,不。
您的 JavaScript 文件可以包含一个类,您可以在视图中实例化该类的新实例,然后您可以ViewBag
在类构造函数中传递值。
或者,如果它不是一个类,您唯一的其他选择是data
在 HTML 元素中使用属性,将它们分配给视图中的属性并在 JS 文件中检索它们。
假设你有这个输入:
<input type="text" id="myInput" data-myValue="@ViewBag.MyValue" />
然后在您的 JS 文件中,您可以使用以下方法获取它:
var myVal = $("#myInput").data("myValue");
在 HTML 中:
<input type="hidden" id="customInput" data-value = "@ViewBag.CustomValue" />
在脚本中:
var customVal = $("#customInput").data("value");
为此,您的 JavaScript 文件需要在服务器端进行预处理。从本质上讲,它必须成为某种 ASP.NET 视图,并且script
引用该文件的标记本质上将引用一个控制器操作,该控制器操作对该视图进行响应。
这听起来像是一罐你不想打开的蠕虫。
由于 JavaScript 是客户端,为什么不直接将值设置为一些客户端元素并让 JavaScript 与之交互。这可能是一个额外的间接步骤,但听起来比创建 JavaScript 视图要少得多。
像这样的东西:
<script type="text/javascript">
var someValue = @ViewBag.someValue
</script>
然后外部 JavaScript 文件可以引用该someValue
文档范围内的 JavaScript 变量。
甚至:
<input type="hidden" id="someValue" value="@ViewBag.someValue" />
然后您可以访问该隐藏的输入。
除非您想出一些非常巧妙的方法来真正使您的 JavaScript 文件可用作视图。这当然是可行的,而且我不能轻易想到你会遇到的任何问题(除了非常丑陋的视图代码,因为视图引擎会对什么是 JavaScript 和什么是 Razor 感到非常困惑......所以期待大量的<text>
标记) ,因此,如果您找到一种巧妙的方法,那将非常酷,尽管对于以后需要支持代码的人来说可能不直观。
在您的 .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>
创建一个视图并将其作为局部视图返回:
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)
//<script>
$(document).ready(function () {
alert('@ViewBag.PropertyName');
});
//</script>
然后在您的最终视图中,您可以像这样添加对 javascript 的引用。
<script src="@Url.Action("GlobalJS", "Assets")"></script>
然后在您的最终视图控制器中,您可以创建/传递您的 ViewBags,它将在您的 javascript 中呈现。
public class MyFinalViewController : Controller
{
public ActionResult Index()
{
ViewBag.PropertyName = "My ViewBag value!";
return View();
}
}
希望能帮助到你。
我注意到,如果您尝试这样做,Visual Studio 的内置错误检测器会变得很愚蠢:
var intvar = @(ViewBag.someNumericValue);
因为 @(ViewBag.someNumericValue) 有可能评估为空,这将导致生成以下错误的 JavaScript:
var intvar = ;
如果您确定 someNemericValue 将设置为有效的数字数据类型,则可以通过执行以下操作来避免出现 Visual Studio 警告:
var intvar = Number(@(ViewBag.someNumericValue));
这可能会生成以下示例:
var intvar = Number(25.4);
它适用于负数。如果该项目不在您的视图包中,则 Number() 评估为 0。
不再有 Visual Studio 警告!但请确保该值已设置并且是数字,否则您将打开可能的 JavaScript 注入攻击或运行时错误的大门。
在控制器动作中添加:
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>
}
对于 CoreMVC 3.1,那将是,
@using Newtonsoft.Json
var listInJs = @Html.Raw(JsonConvert.SerializeObject(ViewBag.SomeGenericList));
onclick="myFunction('@ViewBag.MyValue')"