avianrand Ответов: 2

Проблемы проводки JSON с использованием HttpWebRequest в VB.NET


Я работаю над проектом, чтобы получить данные клиента через vb.net программа-наблюдатель для веб-сервиса. Я не писал для него веб-версию или API. У меня есть доступ к этим разработчикам, но я застрял на чем-то, в чем они не разбираются. Я протестировал свой json в jsonlint, и он идеален. Мой код подключения тоже в порядке. Я проверил это с помощью тестового API, который они создали. Есть еще кое-что, что я упускаю из виду. Я получаю ошибку "плохой запрос", когда запускаю их API загрузки данных. Никакие подробности. Вот и все, что он ко мне возвращает. Они успешно протестировали его на своем конце, используя другой передний конец, но я делаю свою часть работы. vb.net-да.

Edit: я должен отметить, что когда я использую один из API, которые они предоставляют, чтобы вытащить данные из своей системы, это работает нормально. Я могу получить то, что мне нужно. В этом случае мне не нужны строки, которые имеют дело с передачей блока json (связанные с GetRequestStream вещи). Должно быть, я делаю что-то не так в этом отношении.

Edit (2019-03-01): обратите внимание, что я нашел некоторые вариации своего кода и попробовал их также, например, то, что показано на рисунке здесь Есть и другие подобные стратегии, которые утверждают, что работают. Я тоже не мог заставить эту стратегию работать. Я получаю ту же ошибку, что и человек, который отправил этот билет.

Что я уже пробовал:

Вот мой код:

Dim hwReq As HttpWebRequest = Nothing
Dim hwResp As HttpWebResponse = Nothing

Try

    Dim noticeDataBodyContentBytes As Byte() = System.Text.Encoding.Unicode.GetBytes(noticeDataBodyContent)

    hwReq = HttpWebRequest.CreateHttp(webPortalURI)
    hwReq.Method = "POST"
    hwReq.ContentType = "application/json; charset=unicode"
    hwReq.ContentLength = noticeDataBodyContentBytes.Length
    hwReq.Accept = "application/json"
    hwReq.Headers.Add("timestamp", ts)
    hwReq.Headers.Add("apiclient", My.Settings.WebPortalClientID)
    hwReq.Headers.Add("apitoken", atkn)

    Dim noticeDataBodyContentStream As Stream = hwReq.GetRequestStream()
    noticeDataBodyContentStream.Write(noticeDataBodyContentBytes, 0, noticeDataBodyContentBytes.Length)
    noticeDataBodyContentStream.Close()

    hwResp = CType(hwReq.GetResponse, HttpWebResponse) '<<<<< error is here


Catch ex As Exception
    xfrmMain.memWatcherActivity.Text = "ERROR (" & DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") & "): " & friendlyErrorMessage & " - see log file for more info" & vbCrLf & xfrmMain.memWatcherActivity.Text
    errorMessageToLog = "ERROR: " & friendlyErrorMessage & " - " & ex.Message & vbCrLf & ex.StackTrace & vbCrLf & "(" & MethodBase.GetCurrentMethod().ReflectedType.FullName & ".vb." & MethodBase.GetCurrentMethod().Name & ")"
    Utilities.LogToFile(errorMessageToLog)
    If My.Settings.DevMode Then
        MessageBox.Show(errorMessageToLog, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    Else
        SendEmailMessage("ERROR: " & friendlyErrorMessage, errorMessageToLog, emergencyEmailPersonsArray)
    End If

Finally
    If hwResp IsNot Nothing Then
        hwResp.Close()
        hwResp.Dispose()
        hwResp = Nothing
    End If
    hwReq = Nothing

End Try


Я не получаю ответа, когда происходит ошибка. Он переходит к моему обработчику исключений.

Мой блок json находится в переменной noticeDataBodyContent. Как я уже сказал, я протестировал json в jsonlint, и он идеален.

Надеюсь, кто-нибудь даст мне знать, что я здесь делаю не так.

Заранее спасибо!

Кит

Edit (2019-03-01): я изменил свою стратегию на HttpClient и продвинулся немного дальше. Вместо всего вышеперечисленного, я делаю это сейчас:

Dim hc As New HttpClient
hc.DefaultRequestHeaders.Add("timestamp", ts)
hc.DefaultRequestHeaders.Add("apiclient", My.Settings.WebPortalClientID)
hc.DefaultRequestHeaders.Add("apitoken", atkn)
Dim u As New Uri(webPortalURI)
Dim sc As New StringContent(noticeDataBodyContent, Encoding.UTF8, "application/json")
Dim resp = hc.PostAsync(u, sc)
resp.Wait()


Вот что я получаю обратно сейчас:

{StatusCode: 400, ReasonPhrase: 'Bad Request', Версия: 1.1, Содержимое: System.Net.Http.StreamContent, Заголовки:
{
Варьировать: Accept-Encoding
Варьируются: происхождение
Варьировать: accept-encoding
Cache-Control: no-cache
Дата: Пт, 01 марта 2019 14:17:50 GMT
Сервер: nginx/1.15.8
Содержание-Длина: 65
Content-Type: application/json; charset=utf-8
}}

MadMyche

Можно показать, что исключение бывших вернуть?

avianrand

Извиняюсь. Я в основном делал это выше. Там действительно не так уж много полезного. Но вот он здесь:

"Удаленный сервер вернул ошибку: (400) неверный запрос."

Richard Deeming

Попробуйте использовать что-то вроде Скрипач[^] чтобы изучить запрос и ответ, чтобы увидеть, дает ли это вам или разработчикам API какие-либо подсказки.

К сожалению, ошибка "400 плохих запросов" на самом деле не дает нам ничего, чтобы продолжать.

Graeme_Grant

Должно быть внутреннее сообщение об ошибке с дополнительной информацией. Я предполагаю, что вы не аутентифицировались или пропустили токен носителя в заголовке ...

2 Ответов

Рейтинг:
2

avianrand

Сейчас это работает. Почти весь мой код был абсолютно правильным. Единственная проблема заключалась в том, что я должен был использовать UTF8 здесь вместо Unicode для тела json. Их обработка ошибок на другом конце не является достаточной, и независимо от того, что я посылаю, если это плохо каким-то образом, это "плохой запрос" без каких-либо других деталей. Это просто смешно.

Dim noticeDataBodyContentBytes As Byte() = System.Text.Encoding.Unicode.GetBytes(noticeDataBodyContent)


Dim noticeDataBodyContentBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(noticeDataBodyContent)


Рейтинг:
1

Gerry Schmitz

Сдается мне, что ты закрываешь ручей еще до того, как с ним покончишь.

noticeDataBodyContentStream.Close()

hwResp = CType(hwReq.GetResponse, HttpWebResponse) '<<<<< error is here


avianrand

Все примеры, которые я нашел в интернете, делают то же самое. Они закрывают его до получения ответа. И когда я не закрываю его первым, я получаю точно такую же ошибку.