可以从 Javascript 文件访问 MVC ViewBag 对象吗?
Posted
技术标签:
【中文标题】可以从 Javascript 文件访问 MVC ViewBag 对象吗?【英文标题】:Possible to access MVC ViewBag object from Javascript file? 【发布时间】:2012-05-10 12:06:58 【问题描述】:是否可以从 MVC 应用程序中的 javascript 文件执行以下操作?
$(function()
alert(@ViewBag.someValue);
目前它会抛出错误:
引用未定义的 XML 名称 @ViewBag
【问题讨论】:
我之前也问过类似的问题,希望对你有所帮助。 ***.com/questions/10036903/… 它的 tl;dr 是:使用数据属性在视图中设置值,然后使用 jQuery 访问您单独的 .JS 文件中的这些数据属性。 【参考方案1】:我认为目前没有任何方法可以做到这一点。 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>
正如 Joe 在 cmets 中指出的那样,如果上面的字符串值中有一个单引号,它就会中断。如果你想让这个完全铁定,你必须用转义的单引号替换所有的单引号。那里的问题是所有突然的斜线成为一个问题。例如,如果您的字符串是“foo \' bar
”,并且您替换了单引号,那么会出现“foo \\' bar
”,而您又回到了同样的问题。 (这是链式编码的古老难题。)处理此问题的最佳方法是将反斜杠和引号视为特殊,并确保它们全部转义:
@
var safeStringValue = ViewBag.someStringValue
.Replace("\\", "\\\\")
.Replace("'", "\\'");
var someStringValue = '@(safeStringValue)';
【讨论】:
如果你的 ViewBag.someStringValue 中有一个单引号,这不会破坏 js 吗?我相信正确的方法是使用隐藏的表单字段(如下面的答案所示) 这是一个好点,乔,你说得对:单引号确实会搞砸。我觉得隐藏表单字段方法非常笨拙,不过这更直接。并且单引号问题很容易处理......我会相应地更新我的答案,感谢您的提示。 我认为不需要括号 Idk 如果这在以前的版本中是可能的,但您可以直接在警报中输入“@(ViewBag.someStringValue)”(不使用变量)并且仍然会收到基础信息。 谢谢,我认为.Replace("'", "\\');
可能必须是:.Replace("'", "\'");
【参考方案2】:
不在 JavaScript 文件中,不。
您的 JavaScript 文件可以包含一个类,您可以在视图中实例化该类的一个新实例,然后您可以在类构造函数中传递 ViewBag
值。
或者如果它不是一个类,你唯一的选择是在你的 html 元素中使用data
属性,将它们分配给你的视图中的属性,然后在 JS 文件中检索它们。
假设你有这个输入:
<input type="text" id="myInput" data-myValue="@ViewBag.MyValue" />
然后在您的 JS 文件中,您可以使用:
var myVal = $("#myInput").data("myValue");
【讨论】:
+1 - 这是最广泛接受的方法,也是我自己使用的方法 小心将 viewbag 数据存储在 html 元素中,具体取决于您正在构建的数据类型和应用程序类型,这可能是一个严重的安全漏洞。在某些情况下,可能值得通过将一些逻辑从 javascript 移动到控制器来进行重组。 (仅在某些情况下,例如我现在的情况!):) 不过答案很好! 如果 data-myValue 的内容包含 HTML 特殊字符,您可能需要进行一些编码或转义【参考方案3】:在 HTML 中:
<input type="hidden" id="customInput" data-value = "@ViewBag.CustomValue" />
在脚本中:
var customVal = $("#customInput").data("value");
【讨论】:
这必须被选为答案!.. 投票+【参考方案4】:为此,您的 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 是什么...所以期待 ton 的 <text>
标记),所以如果你找到一种巧妙的方法来做这将是非常酷的,尽管对于需要支持的人来说可能不直观后面的代码。
【讨论】:
【参考方案5】:在您的 .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>
【讨论】:
【参考方案6】:创建一个视图并将其作为局部视图返回:
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();
希望对你有帮助。
【讨论】:
【参考方案7】:我注意到,如果您尝试这样做,Visual Studio 的内置错误检测器会变得很愚蠢:
var intvar = @(ViewBag.someNumericValue);
因为@(ViewBag.someNumericValue) 有可能评估为空,这会导致生成以下错误的 JavaScript:
var intvar = ;
如果您确定 someNemericValue 将设置为有效的数字数据类型,则可以通过执行以下操作来避免出现 Visual Studio 警告:
var intvar = Number(@(ViewBag.someNumericValue));
这可能会生成以下示例:
var intvar = Number(25.4);
它适用于负数。如果该项目不在您的 viewbag 中,Number() 的计算结果为 0。
不再有 Visual Studio 警告!但请确保该值已设置并且是数字,否则您将打开可能的 JavaScript 注入攻击或运行时错误的大门。
【讨论】:
【参考方案8】:在控制器动作中添加:
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>
【讨论】:
复制异常集 b=0 ,以便显示弹出窗口【参考方案9】:对于 CoreMVC 3.1,那就是,
@using Newtonsoft.Json
var listInJs = @Html.Raw(JsonConvert.SerializeObject(ViewBag.SomeGenericList));
【讨论】:
【参考方案10】:onclick="myFunction('@ViewBag.MyValue')"
【讨论】:
以上是关于可以从 Javascript 文件访问 MVC ViewBag 对象吗?的主要内容,如果未能解决你的问题,请参考以下文章
将JSON数组从javascript传递给spring mvc控制器
在 MVC 中移动 javascript 后,Active 中的访问被拒绝
javascript asp .net mvc razor中的访问模型