从MVC将数组传递到javascript?

56

我可以使用以下代码从MVC ASP.NET传递变量:

var lastCategoryId = '<%=Model.CS.LastSelectedCategory %>';

这对于字符串或整数可以正常工作,但是如何处理字符串数组?我已经尝试以相同的方式传递数组,但变量被设置为System.String[]?

9个回答

170
您可以使用这一简单代码让.NET来为您处理所有的繁重工作。
此假设您正在使用MVC Razor语法。 var yourJavaScriptArray = @Html.Raw(Json.Encode(Model.YourDotNetArray)); 对于更新版本的MVC,请使用: var yourJavaScriptArray = @Html.Raw(Json.Serialize(Model.YourDotNetArray));

1
这太棒了!不知道 Razor 支持这个,太好了! - Hajjat
5
请注意,Json.Encode()在较新版本的MVC中不再起作用。请改用Json.Serialize(Model.YourDotNetArray) - S.Richmond

43

您可以对其进行JSON序列化。这种方法甚至可以传递更复杂的值,而不必担心转义简单引号、双引号等:

var categoriesList = <%= new JavaScriptSerializer().Serialize(new[] { "value1", "value2" }) %>;

编写一个HTML辅助程序会更好:

public static class HtmlExtensions
{
    public static string JsonSerialize(this HtmlHelper htmlHelper, object value)
    {
        return new JavaScriptSerializer().Serialize(value);
    }
}

在你的视图中:

<script type="text/javascript">
    var categoriesList = <%= Html.JsonSerialize(new[] { "value1", "value2" }) %>;
</script>

6
我必须承认,这种方法比我的回答更简洁明了。应该将其选为解决方案,而不是选择我的帖子。 - Adrian Grigore
2
@Adrian,一切都是主观的。就我个人而言,我讨厌在视图中看到C#代码。而且我特别反感在视图中使用循环 :-) 此外,不对输出的字符串进行编码非常危险,容易受到XSS攻击。这就是为什么我更喜欢始终依赖框架内置的功能,这样我就不必担心正确转义... - Darin Dimitrov
1
每次我看到Darin Dimitrov回答问题,我就知道我会有解决方案。谢谢! - Adrian Marinica

16

这应该可以做到

var someArray=[<%foreach (var s in myStringArray){%>'<%=s%>',<%}%>];

你必须去掉最后一个逗号。 - Omu
1
@Omu:不一定。JavaScript解析器在这方面非常宽容。所有常见的浏览器都不会在数组中出现尾随逗号时出现问题。 - Adrian Grigore
@AdrianGrigore,感谢您的回答。我有同样的问题。但是我从您的答案中找到了一种通过JS传递MVC数组的方法。但我的问题是这种类型的数组需要哪种类型的数组或类,请查看我的问题:http://stackoverflow.com/questions/31911067/how-to-access-server-side-array-clsses-or-subclasses-in-js-file-in-net-mvc - Jatin Gadhiya

3

一句话概括:

var data = [@Html.Raw(String.Join(",", Model.MyArray.Select(i => "'" + i + "'")))];

3

类似这样的内容:

<script type="text/javascript">
var myArr = [<%=string.Join(",", strArr.Select(o => "\"" + o + "\"")) %>];
</script>

这个问题在于它没有将字符串值用引号括起来,这会导致 JavaScript 错误。 - Matthew Manela
@Matthew Manela 谢谢你告诉我,已经修好了。 - Omu
如果 o 包含引号会怎样?如果它包含双引号呢?如果它包含 JavaScript 和 XSS 代码,可能会窃取您的身份验证 cookie?甚至无法想象编写这种代码可能造成的灾难。 - Darin Dimitrov
@Darin Dimitrov,嗯,你说得对,那只是一种简单的方法,也许他不需要编码,谁知道呢。 - Omu

3
非常简单,非常易懂
<script type="text/javascript">
    var array = @Html.Raw(
        Json.Encode(
            (Model).Select(m=> new 
            { 
                id= m.ID, 
                name=m.Name
            })
        )
    );
</script>

输出结果为:
[{"id":1,"name":"Name of 1"}, {"id":2,"name":"Name of 2"}, ...];

3

使用 Json.NET

var yourlist = JSON.parse('@Html.Raw(JsonConvert.SerializeObject(Model.YourList))');

2
你需要将数组格式化为JavaScript数组语法。
var someArray = [<%= Model.SomeArray.Select(x => "'" + x +"'")
                           .Aggregate((x,y) => x + ", " + y);  %>];

这将用单引号包围每个条目,然后用方括号之间的逗号将它们连接在一起。
更新:删除了额外的括号。

抱歉,但是使用这个解决方案时我得到了以下异常 = 预期 ) - Banshee
我多打了一个括号,我把它删掉了。现在再试试看。 - Matthew Manela

0

我想用 Razor 语法提供一个答案:

我们有一个Dictionary<int, int>,我们正在渲染它作为 jQuery Sparkline 的 "数组数组" 形式。

var usageData = [ @string.Join(",", Model.UsageData.Select(d => string.Format("[{0},{1}]", d.Key, d.Value)).ToArray()) ];

这是如何使用的:

$('#sparkline').UsageSparkline(usageData, { tooltipFormatter: cachedTooltips });

这是我们在查看源代码时得到的内容:

var usageData = [ [-13,0],[-12,1],[-11,0],[-10,0],[-9,1],[-8,1],[-7,0],[-6,2],[-5,2],[-4,0],[-3,0],[-2,9],[-1,3],[0,4] ];
$('#sparkline').UsageSparkline(usageData, { tooltipFormatter: cachedTooltips });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接