将 C# ASP.NET 数组传递给 Javascript 数组
Posted
技术标签:
【中文标题】将 C# ASP.NET 数组传递给 Javascript 数组【英文标题】:Pass C# ASP.NET array to Javascript array 【发布时间】:2020-09-03 17:44:24 【问题描述】:有谁知道如何将 C# ASP.NET 数组传递给 javascript 数组?示例代码也会很好。
对不起,如果我之前含糊不清。这个问题其实很简单。为简单起见,假设在我的 aspx.cs
文件中声明:
int [] numbers = new int[5];
现在我想将 numbers
传递给客户端并在 JavaScript 中使用数组中的数据。我该怎么做?
【问题讨论】:
你说的是序列化成 JSON 吗? 我认为我们需要更多详细信息。您想将 if 从代码隐藏传递到 aspx 还是想使用 AJAX 将数据数组发送到 javascript... 或完全不同的东西? 请见上文。抱歉太含糊了。 assign C# string of array or string[] to javascript array的可能重复 【参考方案1】:使用System.Web.Script.Serialization.JavaScriptSerializer
类对其进行序列化并分配给javascript var
虚拟样本:
<% var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); %>
var jsVariable = <%= serializer.Serialize(array) %>;
【讨论】:
抱歉含糊不清。请见上文。 @zerkms 你能解释一下发生了什么吗?对不起,我是菜鸟 @zerkms - 考虑编辑此答案以使其完整并突出它支持任意类型的事实?【参考方案2】:这是对zerkms的回答的补充。
要跨越语言障碍传递数据,您需要一种通过序列化数据将数据表示为字符串的方法。 JavaScript 的序列化方法之一是 JSON。在 zerkms 的示例中,代码将放置在一个 aspx 页面中。要将他的示例和您的示例结合在一个 aspx 页面上,您将拥有,
<%
int[] numbers = new int[5];
// Fill up numbers...
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
%>
稍后在 aspx 页面上的某个地方
<script type="text/javascript">
var jsVariable = <%= serializer.Serialize(numbers) %>;
</script>
不过,此答案假定您是从初始页面加载生成 JavaScript。根据您帖子中的 cmets,这可以通过 AJAX 完成。在这种情况下,您将让服务器响应序列化结果,然后使用您喜欢的框架在 JavaScript 中反序列化它。
注意:也不要将此标记为答案,因为我希望语法突出显示以使另一个答案更清晰。
【讨论】:
你的意思是:var jsVariable = ? 另外,从初始页面加载生成 js 是什么意思? 不,因为您处于生成 JavaScript 的上下文中。当你有 int[] numbers = new int[5] 1, 3, 5, 7, 9 时,序列化它会给你“[1, 3, 5, 7, 9]”。所以生成的javascript就变成了“var jsVariable = [1, 3, 5, 7, 9];” 更正,你是对的,serializer.Serialize(numbers) 带分号。我误读并认为您的意思是分号。我也对代码进行了更正。 由于某种原因这不起作用。 int[] 在后端(aspx.cs 文件),我还在 cs 文件中声明了序列化程序。当我写出脚本标签时,我得到 int[] 在当前上下文中不存在的错误【参考方案3】:您可以使用 ClientScript.RegisterStartUpScript 在 Page_Load 上将 javascript 注入页面。
这是 MSDN 参考的链接: http://msdn.microsoft.com/en-us/library/asz8zsxy.aspx
这是 Page_Load 中的代码:
List<string> tempString = new List<string>();
tempString.Add("Hello");
tempString.Add("World");
StringBuilder sb = new StringBuilder();
sb.Append("<script>");
sb.Append("var testArray = new Array;");
foreach(string str in tempString)
sb.Append("testArray.push('" + str + "');");
sb.Append("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "TestArrayScript", sb.ToString());
注意:使用 StringBuilder 构建脚本字符串,因为它可能会很长。
这是在你可以使用它之前检查注入数组“testArray”的Javascript:
if (testArray)
// do something with testArray
这里有两个问题:
有些人认为这对 C# 注入 Javascript 是一种侵入性
我们必须在全局上下文中声明数组
如果您不能忍受,另一种方法是让 C# 代码将数组保存到视图状态,然后让 JavaScript 使用 PageMethods(或 Web 服务)回调服务器以获取该视图状态对象作为数组。但我认为这样的事情可能有点过头了。
【讨论】:
我会看看谢谢你的解释。一件事,您将哪个数组称为全局数组,为什么? @Gary:我关心的是临时序列化。如果该列表中的字符串包含单引号,我们就会遇到问题。这就是使用 JSON 序列化程序更安全的原因。 @cfarm54:如果你看一下我们必须在哪里声明 testArray 数组,它是 Javascript 中的一个全局变量。是的,在这种情况下,“this”指的是页面。如果你把它放在一个用户控件中,它将返回用户控件类型;将代码注册到控件而不是页面。 @cfarm54:它不应该影响其他脚本。这相当于在您的页面上有多个 @Gary:我关心的是正确性,而不是大小。由于 OP 使用双打并对其进行转换,因此似乎没有任何注入风险。【参考方案4】:在页面文件中:
<script type="text/javascript">
var a = eval('[<% =string.Join(", ", numbers) %>]');
</script>
在代码后面:
public int[] numbers = WhatEverGetTheArray();
【讨论】:
我不确定我是否理解这里的答案...你能帮我解释一下吗? @cfarm54-在后面的代码中,您初始化 int[] 调用的数字。然后在 javascript 中,string.Join(", ", numbers)
将 "numbers" 数组设为类似 "1,2,3,4" 的字符串。之后,我们使用eval('[1,2,3,4]')
将类似数组的字符串转换为数组。
变量“a”将是精确的 js 数组。您可以对它使用任何数组操作,例如a[0] a[1] a.length.【参考方案5】:
对于对象数组:
var array= JSON.parse('@Newtonsoft.Json.JsonConvert.SerializeObject(numbers)'.replace(/"/g, "\""));
对于 int 数组:
var array= JSON.parse('@Newtonsoft.Json.JsonConvert.SerializeObject(numbers)');
【讨论】:
【参考方案6】:准备一个数组(在我的例子中是二维数组):
// prepare a 2d array in c#
ArrayList header = new ArrayList "Task Name", "Hours";
ArrayList data1 = new ArrayList "Work", 2;
ArrayList data2 = new ArrayList "Eat", 2 ;
ArrayList data3 = new ArrayList "Sleep", 2 ;
ArrayList data = new ArrayList header, data1, data2, data3;
// convert it in json
string dataStr = JsonConvert.SerializeObject(data, Formatting.None);
// store it in viewdata/ viewbag
ViewBag.Data = new htmlString(dataStr);
在视图中解析它。
<script>
var data = JSON.parse('@ViewBag.Data');
console.log(data);
</script>
在您的情况下,您可以直接使用变量名而不是 ViewBag.Data。
【讨论】:
【参考方案7】:我遇到了这种类似的情况,我很容易就解决了。这就是我所做的。假设您的 aspx.cs
页面上的数组中已有值。
1)在您的aspx页面中放置一个隐藏字段,并使用隐藏字段ID来存储数组值。
HiddenField2.Value = string.Join(",", myarray);
2)现在隐藏字段已经存储了值,只是用逗号分隔。像这样在 JavaScript 中使用这个隐藏字段。只需在 JavaScript 中创建一个数组,然后通过删除逗号将值存储在该数组中。
var hiddenfield2 = new Array();
hiddenfield2=document.getElementById('<%=HiddenField2.ClientID%>').value.split(',');
这应该可以解决您的问题。
【讨论】:
谢谢,有了所有新的 MVC 和其他技术,我忘记了这个经典:P【参考方案8】:这是另一种替代解决方案。您可以使用 ClientScriptManager Page.ClientScript.RegisterArrayDeclaration。这是图表数据的示例。
var page = HttpContext.Current.CurrentHandler as Page;
_data = "[Date.UTC(2018, 9, 29, 0, 3), parseFloat(21.84)]
,[Date.UTC(2018, 9, 29, 0, 13), parseFloat(21.84)]
,[Date.UTC(2018, 9, 29, 0, 23), parseFloat(21.83)]
,[Date.UTC(2018, 9, 29, 0, 33), parseFloat(21.83)]";
page.ClientScript.RegisterArrayDeclaration("chartdata0", _data);
此代码在客户端创建一个数组
var chartdata0 = new Array([Date.UTC(2018, 9, 29, 0, 3), parseFloat(21.84)]
,[Date.UTC(2018, 9, 29, 0, 13), parseFloat(21.84)]
,[Date.UTC(2018, 9, 29, 0, 23), parseFloat(21.83)]
,[Date.UTC(2018, 9, 29, 0, 33), parseFloat(21.83)]);
请看下面的文章
https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.clientscriptmanager.registerarraydeclaration?view=netframework-4.8
此解决方案在 chrome 64 浏览器上存在较大数组问题,包括“版本 78.0.3904.70(官方构建)(64 位)”。您可能会收到“未捕获的 RangeError:超出最大调用堆栈大小”。但是它可以与 IE11、Microsoft Edge 和 FireFox 一起使用。
【讨论】:
【参考方案9】:简单
整数数组很容易传递。但是,此解决方案也适用于更复杂的数据。在您的模型中:
public int[] Numbers => new int[5];
在您的观点中:
numbers = @(new HtmlString(JsonSerializer.Serialize(Model.Numbers)))
可选
传递字符串的提示。您可能希望 JSON 编码器不转义字符串中的某些符号。在这个例子中,我想要原始的未转义的西里尔字母。在您的观点中:
strings = @(
new HtmlString(
JsonSerializer.Serialize(Model.Strings, new JsonSerializerOptions
Encoder = JavaScriptEncoder.Create(
UnicodeRanges.BasicLatin,
UnicodeRanges.Cyrillic)
)))
【讨论】:
以上是关于将 C# ASP.NET 数组传递给 Javascript 数组的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jquery Ajax 将数组传递给 asp.net C# 控制器
如何将json字符串传递给webmethod c# ASP.NET
如何将值收集到数组中并将集合传递给 C# 中的 datagridview?