【问题标题】:convert json String to datatable?将json字符串转换为数据表?
【发布时间】:2015-08-22 09:24:57
【问题描述】:

在转换 json 字符串数据表时,值字段中存在 ,(逗号)值的问题。

实际上我的 json 字符串是[{"BNo":"345","GNo":"3453","FirstName":"fjai","LastName":"ljai","Address":"BARETI,CEVO, 13/2","Telephone":"051682247","BirthDate":"23-Jan-1981","Email":""}]

那请看地址场景"Address":"BARETI,CEVO, 13/2"

它在值字段中有 ,。将字符串转换为数据库时出现错误。这里我使用的代码将 json 字符串转换为数据表

public DataTable JsonStringToDataTbl(string jsonString)
{
    DataTable dt = new DataTable();
    string[] jsonStringArray = Regex.Split(jsonString.Replace("[", "").Replace("]", ""), "},{");
    List<string> ColumnsName = new List<string>();
    foreach (string jSA in jsonStringArray)
    {
        string[] jsonStringData = Regex.Split(jSA.Replace("{", "").Replace("}", ""), ",");
        foreach (string ColumnsNameData in jsonStringData)
        {
            try
            {
                int idx = ColumnsNameData.IndexOf(":");
                string ColumnsNameString = ColumnsNameData.Substring(0, idx - 1).Replace("\"", "");
                if (!ColumnsName.Contains(ColumnsNameString))
                {
                    ColumnsName.Add(ColumnsNameString);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error Parsing Column Name : {0}", ColumnsNameData));
            }
        }
        break;
    }
    foreach (string AddColumnName in ColumnsName)
    {
        dt.Columns.Add(AddColumnName);
    }
    foreach (string jSA in jsonStringArray)
    {
        string[] RowData = Regex.Split(jSA.Replace("{", "").Replace("}", ""), ",");
        DataRow nr = dt.NewRow();
        foreach (string rowData in RowData)
        {
            try
            {
                int idx = rowData.IndexOf(":");
                string RowColumns = rowData.Substring(0, idx - 1).Replace("\"", "");
                string RowDataString = rowData.Substring(idx + 1).Replace("\"", "");
                nr[RowColumns] = RowDataString;
            }
            catch (Exception ex)
            {
                continue;
            }
        }
        dt.Rows.Add(nr);
    }
    return dt;
}

代码必须在值字段中省略 , .. 我能做什么

【问题讨论】:

  • 为什么不把json转换成对象,然后编辑对象中的属性,然后再转换成数据行?
  • 如果你不介意可以说我该怎么做。实际上 wcf Web 服务将 json 字符串作为输出返回...现在我想更改为表格
  • 如果我是你,我会看看newtonsoft.com/json,它会为你节省很多时间。它使您可以轻松地将 json 转换为对象并返回 :)
  • 或者请告诉我如何从 wcf resfull 服务传递数据表

标签: c# asp.net json


【解决方案1】:

如果您的密钥在被读取时未知,那么您可以使用 JSON.Net 中的 JObjectJProperty 类来检索密钥及其值,如下所示:

private void printKeysAndValues(string json)
{
    var jobject = (JObject)((JArray)JsonConvert.DeserializeObject(json))[0];
    foreach (var jproperty in jobject.Properties())
    {
        Console.WriteLine("{0} - {1}", jproperty.Name, jproperty.Value);
    }
}

应用于两个不同的 JSON 输入字符串,检索键/值对:

var json1 = @"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
var json2 = @"[{""Test"": ""A"", ""Text"":""some text"", ""Numbers"":""123""}]";
printKeysAndValues(json1);
Console.WriteLine("-------------------");
printKeysAndValues(json2);

输出是:

BNo - 345
GNo - 3453
FirstName - fjai
LastName - ljai
Address - BARETI,CEVO, 13/2
Telephone - 051682247
BirthDate - 23-Jan-1981
Email - 
-------------------
Test - A
Text - some text
Numbers - 123

一种可能性是使用dynamic 关键字。您可以像这样直接访问该字段:

var json = @"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
dynamic data = JsonConvert.DeserializeObject(json);
// take the first element of the array
string address = data[0].Address;
Console.WriteLine(address.Replace(",", " "));

输出是:

BARETI CEVO  13/2

注意String.Replace 不会失败,如果应该被替换的符号当前不存在,那么"test".Replace(",", " "); 将返回test

另一种可能性是使用 ASP.NET 中内置的 JSON 转换器(序列化器/反序列化器)-NewtonSoft JSON.Net。您可以使用它来重新获得结构化数据。您需要创建一个代表 JSON 结构的类:

public class Data
{
    public string BNo { get; set; }
    public string GNo { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public string Telephones { get; set; }
    public string BirthDates { get; set; }
    public string Emails { get; set; }
}

然后可以使用JsonConvert.DeserializeObject方法将当前JSON转换为Data类型的对象:

var json = @"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
// remove square braces [ and ] at the start resp. end
var data = JsonConvert.DeserializeObject<Data>(json.Substring(1).Substring(0, json.Length - 2));

现在您可以访问Address 字段,例如替换, 符号:

Console.WriteLine(data.Address.Replace(",", " "));

输出是:

BARETI CEVO  13/2

我认为您的服务也返回了错误的 JSON 格式。 JSON 总是以对象开头(当不在 JavaScript 中时),这意味着顶层的所有内容都必须用大括号 {} 括起来。如果服务应该返回一个数组,那么它应该看起来像这样{"results": [{"BNo":"...},{...}]}。如果您无法更改服务,则可以调整/更正返回的字符串。为数组添加类型化模型:

public class DataHolder
{
    public Data[] data { get; set; }
}

然后创建一个包含数组的正确 JSON 对象:

var data = JsonConvert.DeserializeObject<DataHolder>("{\"data\":" + json + "}");
Console.WriteLine(data.data[0].Address.Replace(",", " "));

输出还是一样的。

【讨论】:

  • 谢谢@pasty,但该专栏是动态的。我能做什么
  • 哪一列是动态的?您的意思是您并不总是名称Address,而是每次都以不同的方式命名列?如果Address 列每次都有不同的内容,那么Replace 将起作用,即使没有, 符号存在!
  • 如果所有列都是动态的,那么Key/Value 结构可能更适合。 namevalue 的获取会容易很多。
  • 所有的列都是动态的,一直不一样。
  • 我已经更新了我的答案 - 我添加了一个从 JSON 字符串中检索键和值的函数。只要 JSON 字符串的结构始终相同,检索将始终有效。
【解决方案2】:

您可以使用Newtonsoft 将 JSON 值转换为 C# 对象。这对你来说很容易。转换为以下对象后,您可以轻松修改Address 属性以删除',' 值。

public class RootObject
{
  public string BNo { get; set; }
  public string GNo { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string Address { get; set; }
  public string Telephone { get; set; }
  public string BirthDate { get; set; }
  public string Email { get; set; }
}

使用下面一行转换为 C# 对象

var jsonString = "The output of your webservice";
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);

现在obj 实例保存了非常容易操作的 C# 对象。

【讨论】:

  • 列将生成动态。执行时就知道了
  • 哪些列都是动态的?
猜你喜欢
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 2015-10-29
  • 2019-11-19
相关资源
最近更新 更多