【问题标题】:Converting a Dictionary to JSON with JSON.NET使用 JSON.NET 将字典转换为 JSON
【发布时间】:2015-05-31 23:54:05
【问题描述】:

我在将字典转换为 JSON.NET 时遇到问题。我确定我遗漏了一些要点。此外,我在使用 JSON 方面的经验很少,而且我主要是从 php 而不是从 c# 中完成的。

它添加了我缺少的 &qout

//GENERAL NOTE: IT's a school project (so not much focus on security)

//C#

public ActionResult GetChartData(string startDate, string endDate)
{
    Dictionary<Movie, double> profitList =  //Gets data from repository

    //in the json list i want the movie names not the objects so I make another dictonairy to convert to json
    Dictionary<string, double> plist = profitList.ToDictionary(keyValuePair => keyValuePair.Key.Title, keyValuePair => keyValuePair.Value);

    //Code from other stackoverflow post
    //http://stackoverflow.com/questions/3739094/serializing-deserializing-dictionary-of-objects-with-json-net

    string json = JsonConvert.SerializeObject(plist, Formatting.Indented, new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All,
        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
    });

    //ViewModel i Use
    FinancialViewModel viewModel = new FinancialViewModel
    {
        ProfitList = profitList,
        ProfitListJson = json,
        Start = start,
        End = end
    };

    return PartialView("_FinancialPartialView", viewModel);
}



//JS
<script>
     var chart = AmCharts.makeChart("chart_6", {
         "type": "pie",
         "theme": "light",

         "fontFamily": "Open Sans",
         "color": "#888",
         "dataProvider": @Model.ProfitListJson,
        "valueField": "movie", //the name from the movie
        "titleField": "profit", //the profit from the movie
        "exportConfig": {
             menuItems: [
                 {
                     icon: Metronic.getGlobalPluginsPath() + "amcharts/amcharts/images/export.png",
                     format: "png"
                 }
             ]
         }
     });

</script>

这是我想要得到的结果

"dataProvider": [{
                "movie": "Title of movie 1",
                "profit": Profit of movie 1
            }, {
                "movie": Title 2c",
                "profit": Profit 2
            }],
            "valueField": "movie",
            "titleField": "profit",

调试时我在控制器中得到的当前结果

chrome 中的结果

我尝试了很多其他 Stackoverflow 答案。我不知道该尝试什么了。

到目前为止谢谢!

【问题讨论】:

  • 您是否要对plist 进行双重序列化——对其进行序列化,然后将字符串嵌入到要重新序列化的类中?还有,为什么要同时返回plist的序列化json和ProfitList字典呢?
  • @dbc 它们都被返回,因为我在部分视图中使用数据表的利润列表。我必须检查您评论的另一部分。
  • Json.NET 不会将具有复杂类的字典序列化为 keys。见here。这里有一些解决方法:How can I serialize/deserialize a dictionary with custom keys using Json.Net?.
  • @dbc 他在序列化之前将其转换为 Dictionary
  • 不,视图模型不会自动序列化,因此它们的属性可以是任何类型。

标签: c# json json.net


【解决方案1】:

使用 jobject (newtonsoft.json.linq) 的答案应该是这样的

JObject o = new JObject
        (
            new JProperty("DataProvider",
                new JArray(
                    from m in List
                    select new JObject(
                        new JProperty("title",m.Key),
                        new JProperty("profit",m.Value))))
        );

那就是你可以使用 o.tostring() 来显示

输出类似于

{
  "DataProvider": [
    {
      "title": "movie1",
      "profit": 2121.0
    },
    {
      "title": "movie2",
      "profit": 47877.0
    }
  ]
}

【讨论】:

    【解决方案2】:

    首先,您应该删除TypeNameHandling = TypeNameHandling.All 设置。这就是您的 JSON 包含 $type 属性的原因。

    其次,您应该使用@Html.Raw(Model.ProfitListJson) 来呈现您的JSON 字符串而不使用&amp;quot

    在你的视图中是这样的:

    var jsonObj = @Html.Raw(Model.ProfitListJson);
    var chart = AmCharts.makeChart("chart_6", {
        //...
        "dataProvider": jsonObj,
        //...
    });
    

    在你的控制器中是这样的:

    string json = JsonConvert.SerializeObject(plist, 
      Formatting.Indented, 
      new JsonSerializerSettings
    {
        TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple // I don't think this is needed, but leaving it in in case you had a reason for it
    });
    

    【讨论】:

    • 快到了!谢谢!当我添加您的 JsonString 示例时,它在 google chrome 中给了我一个非法令牌错误。我会在一秒钟内用结果更新答案
    • 尝试去掉单引号,直接使用模型值。查看我的更新答案
    • 感谢它有效(数据在视图中正确获取)。图表未绘制,但这是另一个需要找出的问题。
    【解决方案3】:

    为了获得带有电影和利润属性的 JSON,您需要创建一个 DTO(数据传输对象)例如

    public class MovieProfit
    {
        public string Title { get; set; }
        public double Profit { get; set; }
    }
    

    然后使用 Linq 将您的字典转换为此 DTO 的列表

    List<MovieProfit> plist = profitList.Select(keyValuePair => new MovieProfit() { Title = keyValuePair.Key.Title, Profit = keyValuePair.Value }).ToList();
    

    您现在将在序列化时获得所需的 JSON。

    关于引号,这是因为您将对象序列化为 JSON 字符串并将该字符串传递回 ViewModel。如果您将对象或对象列表传回,则不会遇到此问题。

    【讨论】:

    • 到目前为止,谢谢,现在在控制器中看起来好多了。有没有在 viewModel 中使用它的解决方案?我需要担心 json 查看器中的 $type 吗(见第一张图片)?
    • 无需担心 $type,但是@Sam 已经回答了如何删除它。我不太明白“有没有在 viewModel 中使用它的解决方案?”
    • sam 回答了那部分。我认为不可能在视图模型中使用它。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 2014-12-31
    相关资源
    最近更新 更多