您可以使用 .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 为您提供了一些开箱即用的功能来完成此任务,并且还有一些 Nuget 提供的良好选项。如果您想利用纯 .NET 功能,您可以结合使用这两个 SO 答案:
您应该能够应用这两个链接中的概念,以及本文第一个“妥协和问题”部分中您需要做出的妥协和明智的决策,以完成您所需要的任务。
我做了类似的事情,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)
如果您想要更强大的东西,那么您始终可以利用这些出色的项目: