【问题标题】:Pass C# ASP.NET array to Javascript array将 C# ASP.NET 数组传递给 Javascript 数组
【发布时间】:2020-09-03 17:44:24
【问题描述】:

有谁知道如何将 C# ASP.NET 数组传递给 JavaScript 数组?示例代码也会很好。

对不起,如果我之前含糊不清。这个问题其实很简单。为简单起见,假设在我的 aspx.cs 文件中声明:

int [] numbers = new int[5];

现在我想将 numbers 传递给客户端并在 JavaScript 中使用数组中的数据。我该怎么做?

【问题讨论】:

  • 你说的是序列化成 JSON 吗?
  • 我认为我们需要更多详细信息。您想将 if 从代码隐藏传递到 aspx 还是想使用 AJAX 将数据数组发送到 javascript... 或完全不同的东西?
  • 请见上文。抱歉太含糊了。

标签: c# javascript asp.net


【解决方案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
}

这里有两个问题:

  1. 有些人认为这对 C# 注入 Javascript 是一种侵入性

  2. 我们必须在全局上下文中声明数组

如果您不能忍受,另一种方法是让 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(/&quot;/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)
            })))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-25
          • 2013-02-03
          • 1970-01-01
          • 2012-02-10
          • 2012-08-23
          • 2011-06-23
          • 1970-01-01
          相关资源
          最近更新 更多