当我需要一个数组时,JSON.Net中的JSON序列化为我提供了对象

时间:2014-08-13 05:48:32

标签: c# asp.net json highcharts json.net

我正在尝试通过ASP.Net的javascript调用填充Highcharts图表,我正在使用JSON.Net来序列化图表的数据。但是,我无法从我的数据源中获取JSON以匹配Highcharts似乎需要的格式。要查看问题,您只需检查X轴(类别),例如......

[{\"category\":\"August 15 and 16, 2014\"},{\"category\":\"March 21st, 2014\"},{\"category\":\"January 17 and 18, 2014\"},{\"category\":\"August 16 and 17, 2013\"},{\"category\":\"March 22nd, 2013\"},{\"category\":\"January 18 and 19, 2013\"},{\"category\":\"August 17 and 18, 2012\"},{\"category\":\"March 16th, 2012\"},{\"category\":\"January 20 and 21, 2012\"},{\"category\":\"August 19 and 20, 2011\"},{\"category\":\"January 21 and 22, 2011\"}]

应该是这样的......

['August 15 and 16, 2014', 'March 21st, 2014', 'January 17 and 18, 2014', 'August 16 and 17, 2013', 'March 22nd, 2013', 'January 18 and 19, 2013', 'August 17 and 18, 2012', 'March 16th, 2012', 'January 20 and 21, 2012', 'August 19 and 20, 2011', 'January 21 and 22, 2011']

基本上我的序列化是创建一个对象列表,我需要的只是一个值数组。要解决这个问题,我需要生成一个值数组,或者让Highcharts构造函数读取对象。

ASP.Net codebehind ...

var tblNormal = Reporting.GetHistoricalTicketSalesReport();

    var queryX = from row in tblNormal.AsEnumerable()
        select new
        {
            category = row.ShowDateDescription
        };
    JObject o = JObject.FromObject(new
    {
        categories = queryX
    });
    string strXJSON = o.ToString();
    // value is: "{\"categories\":[{\"category\":\"August 15 and 16, 2014\"},{\"category\":\"March 21 and 21, 2014\"},{\"category\":\"January 17 and 18, 2014\"},{\"category\":\"August 16 and 17, 2013\"},{\"category\":\"March 22 and 22, 2013\"},{\"category\":\"January 18 and 19, 2013\"},{\"category\":\"August 17 and 18, 2012\"},{\"category\":\"March 16 and 16, 2012\"},{\"category\":\"January 20 and 21, 2012\"},{\"category\":\"August 19 and 20, 2011\"},{\"category\":\"January 21 and 22, 2011\"}]}"

    var queryY = from row in tblNormal.AsEnumerable()
        select new HighChartsPoint
        {
            y = row.TicketsSold
        };
    o = JObject.FromObject(new
    {
        series = queryY
    });
    string strYJSON = o.ToString();

    //This removes the wrapper around the inner JSON data
    strXJSON = F.AllAfter(strXJSON, ":").TrimEnd('}');
    //value is: "[{\"category\":\"August 15 and 16, 2014\"},{\"category\":\"March 21 and 21, 2014\"},{\"category\":\"January 17 and 18, 2014\"},{\"category\":\"August 16 and 17, 2013\"},{\"category\":\"March 22 and 22, 2013\"},{\"category\":\"January 18 and 19, 2013\"},{\"category\":\"August 17 and 18, 2012\"},{\"category\":\"March 16 and 16, 2012\"},{\"category\":\"January 20 and 21, 2012\"},{\"category\":\"August 19 and 20, 2011\"},{\"category\":\"January 21 and 22, 2011\"}]"
    strYJSON = F.AllAfter(strYJSON, ":").TrimEnd('}');

    //Call the function on the client browser
    ExecuteJavascript("InitShowChart(" + strXJSON + ", " + strYJSON + ");");

4 个答案:

答案 0 :(得分:3)

从你的json看,你需要声明的类定义应该是这样的(参见http://json2csharp.com/):

public class Title
{
    public string text { get; set; }
    public int x { get; set; }
}

public class Subtitle
{
    public string text { get; set; }
    public int x { get; set; }
}

public class XAxis
{
    public List<string> categories { get; set; }
}

public class PlotLine
{
    public int value { get; set; }
    public int width { get; set; }
    public string color { get; set; }
}

public class YAxis
{
    public Title title { get; set; }
    public List<PlotLine> plotLines { get; set; }
}

public class Tooltip
{
    public string valueSuffix { get; set; }
}

public class Legend
{
    public string layout { get; set; }
    public string align { get; set; }
    public string verticalAlign { get; set; }
    public int borderWidth { get; set; }
}

public class Series
{
    public string name { get; set; }
    public List<double?> data { get; set; }
}

public class HighChartsData
{
    public Title title { get; set; }
    public Subtitle subtitle { get; set; }
    public XAxis xAxis { get; set; }
    public YAxis yAxis { get; set; }
    public Tooltip tooltip { get; set; }
    public Legend legend { get; set; }
    public List<Series> series { get; set; }
}

如果声明变量

var data = new HighChartsData();

填写其属性并序列化为

var json = JsonConvert.SerializeObject(data);

你的json准备好了。无需手动创建json。

答案 1 :(得分:1)

首先,您可以使用NewtonSoft JSON。他非常新,并经常保留他的图书馆。

其次,这是一个例子。我们假设一个示例类:

public class AnExample{
    public int AnInt{get;set;}
    public string AString {get;set;}
    public DateTime ADate { get; set; }

    public override string ToString() {
        return "['" + AnInt + "','" + AString +"','"+ADate.ToString("s")+"']";
    }
}

你可以这样写:

void Main()
{
    var example = new AnExample() {
          AnInt = 1
        , AString = "Hello"
        , ADate = DateTime.Now
    };

    var examlpe_as_json = Newtonsoft.Json.JsonConvert.SerializeObject(example);
    // -> {"AnInt":1,"AString":"Hello","ADate":"2014-08-13T16:21:56.8348626+10:00"} 

    var input_to_highchart = example.ToString();
    // -> ['1','Hello','2014-08-13T16:21:56']       
}

当你需要将字符串反序列化为一个类时,Json很有用......但是你想要的东西似乎是你的图表的输入。 我没有看到像写上面的ToString()或辅助方法那样的方法。

如果你不关心矿工(我认为你会这么做),你也可以利用一些反思来为你做这件事,但这就是它开始变得更加......丑陋...... :)

答案 2 :(得分:1)

我无法准确地告诉您的代码,但您可能正在尝试序列化List<Category>IEnumerable<Category>或类似内容。这就是你得到[{"category": "xxxxxx"}]构造的原因。

解决方案:相反,首先将其转换为字符串数组:string[],然后序列化该数组。这应该导致一个字符串数组,没有对象。

答案 3 :(得分:0)

这里的其他答案充满了好主意,有些甚至是更好的方法来解决这个问题......但这是我提出的问题的基本解决方案。

我改变了这个......

   var queryX = from row in tblNormal.AsEnumerable()
    select new
    {
        category = row.ShowDateDescription
    };

对此...

var queryX = from row in tblNormal.AsEnumerable()
                 select row.ShowDateDescription;

这解决了主要问题,显然在我缺乏LINQ经验时,我明确地声明了一组对象。新版本仅作为值列表序列化。

采用相同的方法,我也改变了这个......

o = JObject.FromObject(new
{
    series = queryY
});
string strYJSON = o.ToString();
strYJSON = F.AllAfter(strYJSON, ":").TrimEnd('}');

到此......

string strYJSON = JArray.FromObject(queryY).ToString(Newtonsoft.Json.Formatting.None);

该更改消除了在序列化后使用字符串操作的需要,因为我显式地序列化了Array而不是Object。