3

我有一个 ASP.NET MVC 4 应用程序。这个应用程序在页脚中有一个带有 javascript 块的视图。我正在使用 RAZOR 视图引擎。我试图弄清楚如何将我的结果集转换为 JSON 数组。目前,我正在执行以下操作:

<script type="text/javascript">
@for (int i=0; i<ViewBag.States.Count; i++) {
    <text>
        { id: @Html.Raw(ViewBag.States[i]["ID"], name: \"" + ViewBag.States[i]["Name"] + "\"}")
    </text>
    if (i < (ViewBag.States.Count - 1)) {
        <text>,</text>
    }
}
</script>

这种方法在语法上看起来很草率。但是,我不知道该怎么做。有谁知道我该如何清理这个?使用这种方法,我什至无法弄清楚如何将“ID”值用引号括起来。

4

4 回答 4

6

我知道这个问题已经在一年多前得到了回答,但我想添加我的解决方案,恕我直言,这是最干净的。

我基本上做的是这个(使用Newtonsofts Json.Net)。我为 HtmlHelper 类创建了一个扩展方法,如下所示:

public static class HtmlHelperExtensions
{
    public static HtmlString ToJson(this HtmlHelper @this, object value)
    {
        return new HtmlString(JsonConvert.SerializeObject(value));
    }

    public static HtmlString ToJson(this HtmlHelper @this, object value, Formatting formatting)
    {
        return new HtmlString(JsonConvert.SerializeObject(value, formatting));
    }
}

这让我可以做到:

$scope.test = @(Html.ToJson(new []
                    {
                        new {id='1',name="Hello", desc="World"},
                        new {id='1',name="Hello", desc="World"},
                        new {id='1',name="Hello", desc="World"}
                    }));

结果是:

$scope.test = [{"id":"1","name":"Hello","desc":"World"},{"id":"1","name":"Hello","desc":"World"},{"id":"1","name":"Hello","desc":"World"}];

基本上你的例子会变成这样:

@(Html.ToJson(ViewBag.States.Select(s=>new {id=s["ID"], name=s["Name"]})))

或者

@(Html.ToJson(
    from state in ViewBag.States
    select new {id=state["ID"], name=state["Name"]}))
于 2014-10-15T11:23:24.123 回答
2

您可以使用JavaScriptSerializer类将您的集合序列化为 JSON:

@{
   var serializer = new JavaScriptSerializer();
   var serializedData = serializer.Serialize(Enumerable.Select(ViewBag.States, state =>
                                                      new {
                                                            id = state["ID"],
                                                            name = state["Name"]
                                                           }));

}

您可以通过以下方式呈现序列化数据:

@Html.Raw(serializedData)

您可以像这样解析它以供 javascript 使用:

JSON.parse('@Html.Raw(serializedData)');

我认为您的示例中存在某种语法错误,我无法弄清楚您打算使用 Html.Raw() 方法调用的目的,但是您可以对我的代码稍作修改并将方法调用插入到任何位置它是必需的。

于 2013-03-07T21:21:03.567 回答
1

Razor 可以更好地处理基于 xml 的语言,但为了正确起见:这实际上是可能的。

我想你想这样做:

@model IEnumerable<Your.Actual.Namespace.State>
[
@for (int i=0; i < Model.Count; i++) {
    var item = Model[i];
    <text>{ id: @Html.Raw(item["ID"]), name: '@Html.Raw(item["Name"])' }</text>
    if (i < (Model.Count - 1)) 
    {
        <text>,</text>
    }
}
]

调用视图时,这样写:

return View(states);

“states”应该是您之前放入 ViewBag 的“State”对象数组。您以这种方式将其添加为模型,您可以在 .cshtml 中将其用作模型(您可以在我的代码中看到)。

我还稍微清理了您的代码。

我不建议您这样做,但这比使用来自控制器中的对象的 json 序列化程序有一个很大的优势:您可以更改序列化,而无需重新构建代码并将其重新发布到生产服务器。

所以总的来说你的代码会很丑陋,你对此无能为力,但它可以通过编辑 cshtml 在实时应用程序上进行更改。

我会在超过 100 的情况下这样做,但有时这种灵活性可能很重要。但不是你的情况。如果你的 json 有一个预定义的格式,你真的应该使用某种 json 序列化程序,比如 Nico 或 Rickard 建议的。

于 2013-03-07T21:22:26.170 回答
0

如果您不想通过 Ajax 加载它,我建议您在控制器中创建一个模型,然后将其序列化为字符串并将其公开为 @Model 本身或在 ViewBag 中。

一种方法是JsonObjectJSON.NETServiceStack.Text中使用并使用其序列化程序来获取字符串。

于 2013-03-07T21:05:09.367 回答