【问题标题】:Convert objects to JSON in C#在 C# 中将对象转换为 JSON
【发布时间】:2015-10-26 13:42:34
【问题描述】:

我有一堂课:

public class StatististikaByCustomer
{
    public string data { get; set; } // Array or String?
    public string xkey {get;set;}
    public Array ykey {get;set;}
    public Array labels {get;set;}

}

我怎样才能得到这样的 JSON?

{
    "data":[
        {
            "timeinterval":"2015-10-22T00:00:00",
            "Firm":4,
            "Firm1":4,
            "Firm2":22,
            "Firm3":30,
            "Firm4":19
        },
        {
            "timeinterval":"2015-10-23T00:00:00",
            "Firm":2,
            "Firm1":5,
            "Firm2":29,
            "Firm3":34,
            "Firm4":219
        }
    ],
    "xkey":"timeinterval",
    "ykey":["Firm","Firm1","Firm2","Firm3","Firm4"],
    "labels":[" Firm","Firm1","Firm2","Firm3","Firm4"]
}

Firm 不能硬编码。这一切都必须是动态的。

我的控制器动作:

public JsonResult StatistikaJson()
{
    ArrayList arrayList = new ArrayList();
    StatistikaByCustomer statisikaObject = new StatistikaByCustomer();           
    List<Data> listData = new List<Data>();
    string jsonTemp = null;
    DbDataReader reader = null;

    using (var cmd = db.Database.Connection.CreateCommand())
    {
        if (db.Database.Connection.State == ConnectionState.Closed)
        {
            db.Database.Connection.Open();
        }

        cmd.CommandText = "EXEC GetClientConnectsByCustomer @start='" + DateTime.Now.AddMonths(-1).Date.ToString("yyyy-MM-dd") + "',@end='" + DateTime.Now.Date.ToString("yyyy-MM-dd") + "',@interval = 24";
        reader = cmd.ExecuteReader();

        var tempYkey = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToArray();
        statisikaObject.ykey = tempYkey.Select(x => x.Replace(" ", "")).ToArray();

        if (reader.HasRows)
        {
            while (reader.Read())
            {
                string name = reader.GetName(0);
                object value = reader.GetDateTime(0);
                listData.Add(new Data() { Name = name, Value = value });

                for (int i = 1; i < reader.FieldCount - 1; i++)
                {
                    name = reader.GetName(i).Replace(" ", "");
                    value = reader.GetInt32(i);
                    listData.Add(new Data() { Name = name, Value = value });
                }

                //arrayList.Add(JsonConvert.SerializeObject(listData.ToDictionary(x => x.Name, y => y.Value)));
                jsonTemp += JsonConvert.SerializeObject(listData.ToDictionary(x => x.Name, y => y.Value));  
                jsonTemp += ",";                             
                listData.Clear();
                //Debug.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", reader.GetName(0), reader.GetDateTime(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3), reader.GetInt32(4));   
            }
        }
        else
        {
            Debug.WriteLine("No rows found.");
        }
        statisikaObject.xkey = reader.GetName(0);
        statisikaObject.labels = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToArray();
        reader.Close();
        //the number of affected records, if the query returns it var result = cmd.ExecuteNonQuery(); 
        //or a single scalar value //var result = cmd.ExecuteScalar(); 
        //or even a data reader var result = cmd.ExecuteReader(); 
        db.Database.Connection.Close();
    }
    statisikaObject.data =  oSerializer.Serialize(arrayList);

    //string json = JsonConvert.SerializeObject(statisikaObject);
    //string json = JsonConvert.SerializeObject(l);

    return Json(statisikaObject, JsonRequestBehavior.AllowGet);
}

我得到 JSON,但它被转义了,morris.js 不喜欢它。

在我看来,我想这样使用它:

<script type="text/javascript">
    $.getJSON('@Url.Action("StatistikaJson")', function (result)
    {
        new Morris.Line({
            element: 'line-example',
            data: result.data,
            xkey: "timeinterval",
            ykeys: result.ykey,
            labels: result.labels
        });
    });
</script>

如有必要,我可以使用 Json.NET。如果可能的话,我想摆脱附加的 JSON 字符串。我想要一个数组并调用serialize来获取数据:morris.js需要的数组格式的json对象:http://jsbin.com/uqawig/441/embed?js,output

{"data":"{"timeinterval":"2015-10-22T00:00:00","Firm":4,...},{"timeinterval":"2015-10-22T00:00 :00","公司":5,...},...}

【问题讨论】:

  • 您的 JSON 无效,根据 jsonformatter.curiousconcept.com。你能edit你的问题包括有效的JSON吗?
  • 看到这段代码我就头疼。请查看 EntityFramework,它可以让您以 .NET 对象的形式访问您的数据库,包括存储过程
  • 我认为这只有在你知道你的存储过程将返回什么类型的情况下才有可能。在我的例子中,这个存储过程返回动态数据(exec sp_executesql @query)。如果我错了,请纠正我。

标签: json model-view-controller json.net morris.js


【解决方案1】:

视图模型:

public class StatistikaByCustomer
{
    public ArrayList data { get; set; }
    public string xkey { get; set; }
    public List<string> ykey { get; set; }
    public List<string> labels { get; set; }
}

控制器:

public JsonResult StatistikaJson()
{
    StatistikaByCustomer statisikaObject = new StatistikaByCustomer();           
    ArrayList arrayList = new ArrayList();                  
    List<Data> listData = new List<Data>();
    DbDataReader reader = null;
    using (var cmd = db.Database.Connection.CreateCommand())
    {
        if (db.Database.Connection.State == ConnectionState.Closed)
        {
            db.Database.Connection.Open();
        }

        cmd.CommandText = "EXEC GetClientConnectsByCustomer @start='" + DateTime.Now.AddMonths(-1).Date.ToString("yyyy-MM-dd") + "',@end='" + DateTime.Now.Date.ToString("yyyy-MM-dd") + "',@interval = 24";
        reader = cmd.ExecuteReader();

        if (reader.HasRows)
        {
            while (reader.Read())
            {                  
                string name = reader.GetName(0);
                object value = reader.GetDateTime(0).ToString("yyyy-MM-dd");

                listData.Add(new Data() { Name = name, Value = value });

                for (int i = 1; i <= reader.FieldCount - 1; i++)
                {
                    name = reader.GetName(i).Replace(" ", "");
                    value = reader.GetInt32(i);                                               
                    listData.Add(new Data() { Name = name, Value = value });
                }

                arrayList.Add(JsonConvert.SerializeObject(listData.ToDictionary(x => x.Name, y => y.Value)));
                listData.Clear();
                //Debug.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", reader.GetName(0), reader.GetDateTime(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3), reader.GetInt32(4));   
            }               
        }                           
        statisikaObject.data = arrayList;
        statisikaObject.xkey = reader.GetName(0);
        statisikaObject.labels = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToList();
        var tempYkey = Enumerable.Range(1, reader.FieldCount - 1).Select(reader.GetName).ToArray();
        statisikaObject.ykey = tempYkey.Select(x => x.Replace(" ", "")).ToList();
        reader.Close();    
        db.Database.Connection.Close();
    }

    return Json(statisikaObject, JsonRequestBehavior.AllowGet);
}

查看:

<script type="text/javascript">    
    $.getJSON('@Url.Action("StatistikaJson")', function (result)
    {
        new Morris.Line({
            element: 'line-example',
            data: $.parseJSON("[" + result.data + "]"),
            xkey: result.xkey,
            ykeys: result.ykey,
            labels: result.labels
    });
    });
</script>

【讨论】:

    【解决方案2】:
    public class Datum
    {
        public string timeinterval { get; set; }
        public int Firm { get; set; }
        public int Firm1 { get; set; }
        public int Firm2 { get; set; }
        public int Firm3 { get; set; }
        public int Firm4 { get; set; }
    }
    
    public class RootObject
    {
        public List<Datum> data { get; set; }
        public string xkey { get; set; }
        public List<string> ykey { get; set; }
        public List<string> labels { get; set; }
    }
    

    通过把这段代码得到序列化json字符串

    var collection = new List<RootObject>();
    
    dynamic collectionWrapper = new
    {
        people = new RootObject()
        {
            xkey = "timeinterval",
            data = new List<Datum> 
            { 
                new Datum() 
                { 
                    timeinterval = "2015-10-22T00: 00: 00", 
                    Firm = 4,
                    Firm1= 4,
                    Firm2= 22,
                    Firm3= 30,
                    Firm4= 19
                },
                new Datum() 
                { 
                    timeinterval = "2015-10-23T00: 00: 00", 
                    Firm = 2,
                    Firm1= 5,
                    Firm2= 29,
                    Firm3= 34,
                    Firm4= 219
                }
            },
            ykey = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
            labels = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" }
        }
    };
    var output = JsonConvert.SerializeObject(collectionWrapper);
    

    编辑:

    var collection = new StatististikaByCustomer
    {
        xkey = "timeinterval",
        ykey = new List<string>{"Firm","Firm1","Firm2","Firm3","Firm4"},
        labels = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
        data = new Dictionary<string, string>
        {
            { "timeinterval", "2015-10-22T00: 00: 00" },
            { "Firm", "4" },
            { "Firm1", "4" },
            { "Firm2", "22" },
            { "Firm3", "30" },
            { "Firm4", "19" }
        }
    };
    
    string json = JsonConvert.SerializeObject(collection);
    

    类:

    public class StatististikaByCustomer
    {
        public string xkey { get; set; }
        public Dictionary<string, string> data { get; set; }
        public List<string> ykey { get; set; }
        public List<string> labels { get; set; }
    
    }
    

    更新:

    var collection = new StatististikaByCustomer
    {
        xkey = "timeinterval",
        ykey = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
        labels = new List<string> { "Firm", "Firm1", "Firm2", "Firm3", "Firm4" },
        data = new List<Dictionary<string,string>>
        {
            new Dictionary<string, string>
            {
                { "timeinterval", "2015-10-22T00: 00: 00" },
                { "Firm", "4" },
                { "Firm1", "4" },
                { "Firm2", "22" },
                { "Firm3", "30" },
                { "Firm4", "19" }
            },
            new Dictionary<string, string>
            {
                { "timeinterval", "2015-10-23T00: 00: 00" },
                { "Firm", "2" },
                { "Firm1", "5" },
                { "Firm2", "29" },
                { "Firm3", "34" },
                { "Firm4", "219" }
            }
        }
    };
    
    string json = JsonConvert.SerializeObject(collection);
    

    类:

    public class StatististikaByCustomer
    {
        public string xkey { get; set; }
        public List<Dictionary<string, string>> data { get; set; }
        public List<string> ykey { get; set; }
        public List<string> labels { get; set; }
    
    }
    

    【讨论】:

    • 但是我怎样才能变成动态的 Datum 类。示例:明天有人会添加新公司...Firm5。我不想每次有人添加新公司时都换班。我从 DataReader 获取数据。第一列是日期,其他都是数字。我将列名称和列值作为键和值并将其添加到 List 并尝试从列表中创建一个 json 字符串并将其保存到 RootObject 中的 Data 但它不起作用。我需要以某种方式从键值对或字典中为每一行创建 json 字符串,并将该行添加到 List。然后我可以使用 JsonConvert.SerializeObject(collectionWrapper);
    • 您的示例非常有用,我找到了解决方案。在视图中我必须解析 ajax 结果数据: $.parseJSON("[" + result.data + "]").
    • @LoZo 我更新我的答案检查一下,你会得到更好的主意
    猜你喜欢
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 2018-05-24
    相关资源
    最近更新 更多