Возвращение Json байтового массива в веб-API c# - PullRequest
0 голосов
/ 12 апреля 2020

Привет! Я разработал Web API, в котором я беру некоторые параметры в URL и затем обрабатываю их. Я использую протокол Modbus. Он возвращает байтовый массив, а взамен я хочу получить из него некоторые специфические c строковые данные. Ниже приведен мой код

  public string GetData(int slaveId, int dataAddress, int registerCount)
    {

        //string hexValue = intValue.ToString("X");
        // Convert the hex string back to the number
        int slaveHex = int.Parse(slaveId.ToString("X"), System.Globalization.NumberStyles.HexNumber);
        int addressHex = int.Parse(dataAddress.ToString("X"), System.Globalization.NumberStyles.HexNumber);
        int countHex = int.Parse(registerCount.ToString("X"), System.Globalization.NumberStyles.HexNumber);


        //serial port settings and opening it
        var serialPort = new SerialPort("COM2", 9600, Parity.Even, 8, StopBits.One);

        serialPort.Open();

        var stream = new SerialStream(serialPort);
        stream.ReadTimeout = 200;
        // send request and waiting for response
        // the request needs: slaveId, dataAddress, registerCount            
        var responseBytes = stream.RequestFunc3(slaveHex, addressHex, countHex);

        // extract the content part (the most important in the response)
        var data = responseBytes.ToResponseFunc3().Data;         

        //Convert a byte array to string
        var stringFromByteArray = System.Text.Encoding.UTF8.GetString(data);
        serialPort.Close();

        return stringFromByteArray;
    }

data содержит массив из 14 байтов

enter image description here

stringFromByteArray возвращает следующий

"\0�\0�\0�\0\u0016\0\u0017\0\u0018\0\u001a"

Как вы можете видеть выше, возвращаемая строка не соответствует ожидаемой. Я хочу точные значения, как в байтовом массиве данных.

Полученный результат я хочу, чтобы он был в Json response. Как показано ниже

{
  [0] => "220",
  [1] => "230",
  [2] => "240", 
  [3] => "22",
  [4] => "23",
  [5] => "24",
  [6] => "26",
} 

Как я могу это сделать? Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 12 апреля 2020

В широком смысле, вам доступно несколько вариантов.

Прежде всего, вы можете рассмотреть возможность использования application/octet-stream в качестве типа ответа вместо application/json в ответе HTTP. application/octet-stream означает, что байты отправляются напрямую по HTTP. Так вы обычно загружаете / скачиваете файлы.

Во-вторых, можно кодировать двоичные данные в текст более безопасным способом, например, используя алгоритмы кодирования, такие как Base64 , которые вы можете достигните дюйма NET, используя Convert.ToBase64String метод. Такие методы более многословны, чем использование octet-stream, но они также лучше работают при попытке отправки структурированных данных с некоторым двоичным содержимым.

И, наконец, как вы просили, вы можете использовать структуру для непосредственного представления данных. Есть несколько опций, вы можете напрямую кодировать массив чисел, что даст вам JSON полезную нагрузку в виде:

[220, 230, 240, 22, 23, 24, 26]

Чтобы достичь этого, вы просто сериализуете список чисел, например, byte[] напрямую или, возможно, int[] в зависимости от поведения вашего сериализатора (. NET Core 3.0+ System.Test. Json .JsonSerializer преобразует байтовые массивы в base64, поэтому необходимо преобразование в int[]). Живой образец .

Запрошенная вами структура не представляется возможной непосредственно в JSON, но вы можете добиться чего-то подобного сериализации Dictionary<string, string>, получая структуру { "0": "220", "1": "230", "2":"240" ... }. Однако обратите внимание, что эта структура довольно многословна и не очень практична.

Вы можете получить словарь, используя следующий фрагмент:

var bytes = new byte[] { 220, 230, 240, 22, 23, 24, 26 };

var dictionary = bytes
    .Select((b, i) => (value: b, index: i)) // convert bytes to sequence of (byte value, index)
    .ToDictionary(x => x.index.ToString(), x => x.value.ToString());
...