如何从字符串内容填充对象并填充列表?

时间:2019-07-12 11:00:09

标签: c# string http gzip

我有一个通过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
            });
        }

有更好的方法吗?

2 个答案:

答案 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中看起来像这样:

enter image description here

答案 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

使用的正则表达式:(?<==)(.*?)(?=&)

说明:

  1. 正向(?<==)后看:与字符=完全匹配(区分大小写)
  2. 第一捕获组(.*?).*?匹配任何字符(行终止符除外)。 *?量词-匹配零次和无限制次数,尽可能少地次数,并根据需要扩展。
  3. 正向超前(?=&):与字符&完全匹配(区分大小写)