我有一个通过HTTP Web Request发送的字符串,该字符串使用GZIP压缩并包含以下数据:
[Route("Test")]
public IActionResult Test()
{
var data = "[0].meetingDate=2019-07-12&[0].courseId=12&[0].raceNumber=1&[0].horseCode=000000331213&[1].meetingDate=2019-07-12&[1].courseId=12&[1].raceNumber=1&[1].horseCode=000000356650";
try
{
var req = WebRequest.Create("https://localhost:44374/HorseRacingApi/Prices/GetPriceForEntries");
req.Method = "POST";
req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
req.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip");
if (!string.IsNullOrEmpty(data))
{
var dataBytes = Encoding.ASCII.GetBytes(data);
using (var requestDS = req.GetRequestStream())
{
using (var zipStream = new GZipStream(requestDS, CompressionMode.Compress))
{
zipStream.Write(dataBytes, 0, dataBytes.Length);
}
requestDS.Flush();
}
}
HttpWebResponse response = (HttpWebResponse)req.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
Debug.WriteLine("Response stream received.");
Debug.WriteLine(readStream.ReadToEnd());
response.Close();
readStream.Close();
return Ok("Sent!");
}
catch(Exception ex)
{
throw ex;
}
}
我正在此函数中接收http数据并将其解压缩:
[HttpPost]
[Route("GetPriceForEntries")]
[DisableRequestSizeLimit]
public JsonResult GetPriceForEntries(bool? ShowAll)
{
string contents = null;
using (GZipStream zip = new GZipStream(Request.Body, CompressionMode.Decompress))
{
using (StreamReader unzip = new StreamReader(zip))
{
contents = unzip.ReadToEnd();
}
}
//CONVERT CONTENTS TO LIST HERE?
return Json("GOT");
}
我有一个对象/模型设置:
public class JsonEntryKey
{
public DateTime meetingDate { get; set; }
public int courseId { get; set; }
public int raceNumber { get; set; }
public string horseCode { get; set; }
}
如何将此“字符串”转换为上面的List对象?
我通过压缩发送数据的原因是因为有时数据会很大。
欢呼
编辑:这是我创建所有者“转换器”的尝试
//Convert string to table.
string[] unzipString = contents.Split('=','&');
List<Core.Models.JsonEntryKey> entries = new List<Core.Models.JsonEntryKey>();
for (int i = 1; i < entries.Count; i += 8)
{
DateTime meetingDate = Convert.ToDateTime(entries[i]);
int courseId = int.Parse(unzipString[i + 2]);
int raceNumber = int.Parse(unzipString[i + 4]);
string horseCode = unzipString[i + 6];
entries.Add(new Core.Models.JsonEntryKey
{
meetingDate = meetingDate,
courseId = courseId,
raceNumber = raceNumber,
horseCode = horseCode
});
}
有更好的方法吗?
答案 0 :(得分:3)
基本解析可以通过3个步骤完成。
1)Split用'&'
string [] parts = data.Split('&')
您最终得到了单个部分:
[0].meetingDate=2019-07-12
[0].courseId=12
[0].raceNumber=1
[0].horseCode=000000331213
[1].meetingDate=2019-07-12
[1].courseId=12
[1].raceNumber=1
[1].horseCode=000000356650
2)现在您可以GroupBy括号中的数字,因为它似乎表示对象[0]
,[1]
,...的索引。用{{ 1}},并选择第一个元素:
'.'
3)现在,对于每个组(基本上是有关每个对象的属性信息的集合),您需要遍历属性,通过反射找到相应的属性并设置值。最后:别忘了将新创建的对象收集到集合中:
var items = parts.GroupBy(x => x.Split('.').First());
字符串的结果在LINQPad Dump中看起来像这样:
答案 1 :(得分:1)
我想分享的另一种解决方案是基于Regex
的解决方案。我为该字符串构建的正则表达式将在字符串的末尾附加&
字符后起作用,并且基于正则表达式逻辑,将从字符串中解析出所需的数据。这只是如何使用正则表达式处理字符串方案的示例。关于性能根据官方规格:
.NET中的正则表达式引擎是功能强大的功能齐全的工具,可基于模式匹配而不是根据比较和匹配文字文本来处理文本。在大多数情况下,它可以快速有效地执行模式匹配。但是,在某些情况下,正则表达式引擎可能看起来非常慢。在极端情况下,它甚至可能在数小时甚至数天的时间内处理相对较小的输入,从而停止响应。
正则表达式的性能取决于字符串的长度和正则表达式的复杂性。关于您的字符串data
,我在这里准备了DEMO。
代码如下:
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
var data = "[0].meetingDate=2019-07-12&[0].courseId=12&[0].raceNumber=1&[0].horseCode=000000331213&[1].meetingDate=2019-07-12&[1].courseId=12&[1].raceNumber=1&[1].horseCode=000000356650";
var dataRegex=data+"&";
//Console.WriteLine(dataRegex);
showMatch(dataRegex, @"(?<==)(.*?)(?=&)");
}
private static void showMatch(string text, string expr) {
MatchCollection mc = Regex.Matches(text, expr);
foreach (Match m in mc) {
Console.WriteLine(m);
}
}
}
输出为:
2019-07-12
12
1
000000331213
2019-07-12
12
1
000000356650
使用的正则表达式:(?<==)(.*?)(?=&)
说明:
(?<==)
后看:与字符=
完全匹配(区分大小写)(.*?)
:.*?
匹配任何字符(行终止符除外)。 *?
量词-匹配零次和无限制次数,尽可能少地次数,并根据需要扩展。(?=&)
:与字符&
完全匹配(区分大小写)