C# 中的 JSON 到 CSV 和 CSV 到 JSON

Nic*_*ips 2 c# csv parsing json

我一直在寻找一种使用 C# 将 json 文件转换为 csv 的方法,反之亦然。我已经搜索过谷歌,但没有得到任何结果。到目前为止,我尝试过的所有关于堆栈溢出的答案都对我不起作用。有谁知道我可以使用哪些工具或教程来了解如何使用 .NET Framework 来完成此任务?通常我会发布我尝试过的内容,但是我显然离这里很远,所以这是毫无意义的。

Jax*_*ian 5

妥协和问题

您可以使用 .NET Framework 来完成此任务,但由于层次结构和集合的原因,没有一种清晰明了的方法可以直接完成此任务。我的意思是,CSV 数据非常扁平且非结构化,而 JSON 数据则非常有组织且可迭代。让我们看一个简单的 JSON 数据块,如下所示:

{
    "Data": [
        {
            "Name":"Mickey Mouse",
            "Friends":[ "Pluto", "Minnie", "Donald" ]
        },
        {
            "Name":"Pluto",
            "Friends":[ "Mickey" ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

最明显的 CSV 文件可能是:

Name,Friend
Mickey Mouse,Pluto
Mickey Mouse,Minnie
Mickey Mouse,Donald
Pluto,Mickey
Run Code Online (Sandbox Code Playgroud)

这是更容易的转换,但假设您只有该 CSV 文件。JSON 应该是什么样子并不是那么明显。有人可能会说 JSON 应该如下所示:

{
    "Data": [
        { "Name":"Mickey Mouse", "Friend":"Pluto" },
        { "Name":"Mickey Mouse", "Friend":"Minnie" },
        { "Name":"Mickey Mouse", "Friend":"Donald" },
        { "Name":"Pluto", "Friend":"Mickey" },
    ]
}
Run Code Online (Sandbox Code Playgroud)

生成的 JSON 文件与输入 JSON 文件非常不同。我的观点是,这不是一个简单/明显的转换,因此任何现成的或复制/粘贴的解决方案都是不完美的。无论您的解决方案是什么,您都必须做出妥协或做出明智的决定。


.NET 框架选项

现在我们已经解决了这个问题,.NET 为您提供了一些开箱即用的功能来完成此任务,并且还有一些 Nuget 提供的良好选项。如果您想利用纯 .NET 功能,您可以结合使用这两个 SO 答案:

  1. 并不完美,但这个答案有一些很棒的代码可以帮助您开始生成 CSV 文件的逻辑
  2. 这个问题和由此产生的答案提供了一些有关仅使用 .NET Framework 而无需任何第三方实用程序生成 JSON 的好信息。

您应该能够应用这两个链接中的概念,以及本文第一个“妥协和问题”部分中您需要做出的妥协和明智的决策,以完成您所需要的任务。


我以前做过的事

我做了类似的事情,Microsoft.VisualBasic.FileIO除了 Web API 的序列化功能之外,我实际上在命名空间中使用了一些功能(在 C# 应用程序中效果很好),以使用动态对象(使用动态关键字)作为中介来完成 CSV->JSON 转换。下面提供了代码。它不是非常强大并且做出了一些重大妥协,但它对我来说效果很好。如果您想尝试此操作,则必须创建自己的相反版本,但正如我在第一部分中提到的,这确实是最简单的部分。

using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Web.Http;

// NOTE: This is not purely my code. This was put together
// with the help of other SO questions that I wish I had the
// links to so I could credit them. You probably will find
// some chunk(s) of this code elsewhere on SO.

namespace Application1.Controllers
{
    public class Foo
    {
        public string Csv { get; set; }
    }
    public class JsonController : ApiController
    {
        [HttpPost]
        [Route("~/Csv/ToJson")]
        public dynamic[] ConvertCsv([FromBody] Foo input)
        {
            var data = CsvToDynamicData(input.Csv);
            return data.ToArray();
        }

        internal static List<dynamic> CsvToDynamicData(string csv)
        {
            var headers = new List<string>();
            var dataRows = new List<dynamic>();
            using (TextReader reader = new StringReader(csv))
            {
                using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(reader))
                {
                    parser.Delimiters = new[] {","};
                    parser.HasFieldsEnclosedInQuotes = true;
                    parser.TrimWhiteSpace = true;

                    var rowIdx = 0;

                    while (!parser.EndOfData)
                    {
                        var colIdx = 0;
                        dynamic rowData = new ExpandoObject();
                        var rowDataAsDictionary = (IDictionary<string, object>) rowData;

                        foreach (var field in parser.ReadFields().AsEnumerable())
                        {
                            if (rowIdx == 0)
                            {
                                // header
                                headers.Add(field.Replace("\\", "_").Replace("/", "_").Replace(",", "_"));
                            }
                            else
                            {
                                if (field == "null" || field == "NULL")
                                {
                                    rowDataAsDictionary.Add(headers[colIdx], null);
                                }
                                else
                                {
                                    rowDataAsDictionary.Add(headers[colIdx], field);
                                }

                            }
                            colIdx++;
                        }

                        if (rowDataAsDictionary.Keys.Any())
                        {
                            dataRows.Add(rowData);
                        }

                        rowIdx++;
                    }
                }
            }

            return dataRows;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想要更强大的东西,那么您始终可以利用这些出色的项目:

  1. JSON.NET(这对于从动态对象创建 JSON 非常有效。鉴于您没有使用 Web API,这将是我想要获取返回dynamic[]值并将其转换为 JSON 的第一个地方。)
  2. CSV助手