C#解析CSV以JSON格式错误

问题描述:

看看,让我知道我derping上的地狱是什么;)C#解析CSV以JSON格式错误

[HttpPost] 
public ActionResult Upload(HttpPostedFileBase File) 
{ 

    HttpPostedFileBase csvFile = Request.Files["adGroupCSV"]; 

    byte[] buffer = new byte[csvFile.ContentLength]; 
    csvFile.InputStream.Read(buffer, 0, csvFile.ContentLength); 

    string csvString = System.Text.Encoding.UTF8.GetString(buffer); 

    string[] lines = Regex.Split(csvString, "\r"); 
    List<string[]> csv = new List<string[]>(); 

    foreach (string line in lines) 
    { 
     csv.Add(line.Split(',')); 
    } 

    string json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(csv); 

     ViewData["CSV"] = json; 

     return View(ViewData); 
} 

这是它是如何在即将到来:

json = "[[\"Col1\",\"Col2\",\"Col3\",\"Col4\",\"Col5\",\"Col6\"],[\"test\",\"test\",\"test\",\"test\",\"http://www.test.com/\",\"test/\"],[\"test\",\"test\",\"test\",\"test\",\"http://www.test.com... 

这就是我想要的:

{"Col1":"test","Col2":"test","Col3":"test","Col4":"test","Col5":"http://www.test.com/","Col6":"test/"} 

这里的CSV

为例
Col1,Col2,Col3,Col4,Col5,Col6 
Test1,Test1,Test1,test1,test.test,test/ 
Test2,Test2,Test2,test2,test.test,test/ 
Test3,Test3,Test3,test3,test.test,test/ 
Test4,Test4,Test4,test4,test.test,test/ 
+1

+1 “derping”。从来没有听说过。我喜欢它! – JMarsch 2013-03-18 18:22:26

+0

你可以折腾输入文件的样本吗? – JMarsch 2013-03-18 18:26:30

+0

那么,你是否明白这一点?仍然有问题? – 2013-03-18 19:07:04

你需要一本字典。只需更换

List<string[]> csv = new List<string[]>(); 

foreach (string line in lines) 
{ 
    csv.Add(line.Split(',')); 
} 

var csv = lines.Select(l => l.Split(',') 
          .Select((s,i)=>new {s,i}) 
          .ToDictionary(x=>"Col" + (x.i+1), x=>x.s)); 

它应该工作...

编辑

var lines = csvString.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); 
var cols = lines[0].Split(','); 
var csv = lines.Skip(1) 
       .Select(l => l.Split(',') 
          .Select((s, i) => new {s,i}) 
          .ToDictionary(x=>cols[x.i],x=>x.s)); 

var json = new JavaScriptSerializer().Serialize(csv); 
+0

非常接近,但不是“Col”+(x.i + 1)我想使用CSV中提供的列名称 – 2013-03-18 19:11:46

+0

@BrentonPierce请参阅编辑。 – I4V 2013-03-18 19:28:32

+0

谢谢@ I4V那样做! – 2013-03-19 12:49:57

它看起来像你有一个字符串数组的数组,当你只想要一个对象与你的所有列作为它的属性。

而是建立你的

List<string[]> csv = new List<string[]>(); 

可以从您的JSON做出一个新的对象,像这样:

public class UploadedFileObject 
{ 
    public string Col1 { get; set; } 
    public string Col2 { get; set; } 
    public string Col3 { get; set; } 
    public string Col4 { get; set; } 
    public string Col5 { get; set; } 
    public string Col6 { get; set; } 
} 





[HttpPost] public ActionResult Upload(HttpPostedFileBase File) 
{ 

HttpPostedFileBase csvFile = Request.Files["adGroupCSV"]; 

byte[] buffer = new byte[csvFile.ContentLength]; 
csvFile.InputStream.Read(buffer, 0, csvFile.ContentLength); 

string csvString = System.Text.Encoding.UTF8.GetString(buffer); 

string[] lines = Regex.Split(csvString, "\r"); 
List<UploadedFileObject> returnObject = new List<UploadedFileObject>(); 

foreach (string line in lines) 
{ 
    String[] lineParts = line.Split(','); 
    UploadedFileObject lineObject = new UploadedFileObject(); 
    lineObject.Col1 = lineParts[0]; 
    lineObject.Col2 = lineParts[1]; 
    lineObject.Col3 = lineParts[2]; 
    lineObject.Col4 = lineParts[3]; 
    lineObject.Col5 = lineParts[4]; 
    lineObject.Col6 = lineParts[5]; 

    returnObject.add(lineObject); 
} 

string json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(returnObject); 

    ViewData["CSV"] = json; 

    return View(ViewData); 
} 
+0

根据这个答案,也许你可以使用ServiceStack将CSV反序列化为一个对象数组,然后使用ServiceStack的JSON序列化器重新序列化它? http://www.servicestack.net/docs/text-serializers/json-csv-jsv-serializers – theMayer 2013-03-18 18:31:21

+0

我会给第一个答案一个镜头,不想使用第三方。 – 2013-03-18 18:34:07

+0

行csv.add(line.split(','));不是那样的 – 2013-03-18 18:38:43

你需要确保你使用的是JavaScriptSerializer期待您的格式至。

既然你给它一个List<string[]>它被格式化为:

"[[list1Item1,list1Item2...],[list2Item1,list2Item2...]]" 

这会在你的文件关联ROW1 - >列表1等

不过你想要的是从第一个项目第一个列表,与第二个列表中的第一个项目对齐,等等。

我不知道JavaScriptSerializer的确切工作原理,但假设您只有一行数据(总共两行),您可以尝试给它一个Dictionary而不是List<string[]>

这将涉及缓存的前两行,并执行以下操作:

for (int i = 0; i < first.Length; i++) 
{ 
    dict.Add(first[i],second[i]); 
} 

与以前的答案线,也许你可以使用ServiceStack到CSV反序列化为对象的数组,然后重新序列它使用ServiceStack的JSON序列化程序?

http://www.servicestack.net/docs/text-serializers/json-csv-jsv-serializers