質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

3回答

13537閲覧

VB.NET(2010)でJSONをリクエスト送信したいのですが

akiras

総合スコア8

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2019/01/30 06:34

編集2019/01/31 00:55

##【やりたいこと】
・VB.NETでJSONデータを送信したいのですが、エラーが消えません
→ リストリモート サーバーがエラーを返しました: (400) 要求が不適切です
・簡易的にリクエストを受取るソースを作りました(リクエストデータをそのまま返すだけ)
・ARC(google Chromeの拡張機能‎)でリクエストすると、正しく返ります

##【環境】
visual stadio 2010
VB.NET 2010
.net framework 4.0

##【ソース・サーバー側の簡易コントローラ】
<ServiceContract(namespace:="http://aaa/bbb/api/ccc/")>
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
Public Class KaniCntl

Inherits System.Web.UI.Page '-------------------------------------------------------------------- ' report簡易コントローラー(構造型のリクエストJSONをそのまま返す) '--------------------------------------------------------------------

<OperationContract(), WebInvoke()>
Public Function report(req As List(Of RequestJson3)) As List(Of RequestJson3)

Dim RequestHeaders = WebOperationContext.Current.IncomingRequest.Headers ' リクエストヘッダー Return req End Function

End Class

##【JSON定義側】
'--------------------------------------------------------------------
' リクエスト・メインクラス(JSON List)
'--------------------------------------------------------------------
Public Class RequestJson3
Property headerlist3 As New List(Of HeaderList3) '--- 配列データ 
Property reqdat3 As New List(Of DataList3) '--- 配列データ 
End Class

'--------------------------------------------------------------------
' リクエスト・ヘッダークラス(List)
'--------------------------------------------------------------------
Public Class HeaderList3
Property recordNo As String = "" '--- レコード番号
Property appVer As String = "" '--- 識別情報
Property houkokuTime As String = "" '--- データ作成日時
End Class

'--------------------------------------------------------------------
' リクエスト・データクラス(List)
'--------------------------------------------------------------------
Public Class DataList3
Property recordNo As String = "" '--- レコード番号
Property okozukai As String = "" '--- お小遣い
Property actiondate As String = "" '--- 使った日
End Class

  ※もちろん、実際の中身とは異なります

##【ソース・リクエスト側】
Private Function RequestToPMS3(ByRef json As RequestJson3) As String

'文字コードを指定する Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("UTF-8") 'POST送信する文字列を作成 Dim postData As String postData = System.Web.HttpUtility.UrlEncode(json.ToString, enc)  `※ JSONではなく、"xxx.RequestJson3"の文字になっている` 'バイト型配列に変換 Dim postDataBytes As Byte() = enc.GetBytes(postData) Dim wc As New System.Net.WebClient '--- ヘッダ --- ' Content-Type wc.Headers.Add("Content-Type", "application/json; charset=utf-8") ' 連携リクエストID wc.Headers.Add("X-Request-Id", getRequestId()) Dim eMsg As String = "" Try '***** データを送信し、結果を受信する ***** reqCount = reqCount + 1 Dim resData As Byte() resData = wc.UploadData(pmsRequestUrl, postDataBytes)    `※ここで400のエラーになります` wc.Dispose() '受信した結果(JSONデータ)を表示する Dim resText As String = enc.GetString(resData) Console.WriteLine(resText)

     ~



End Function

##【問い合わせ内容】
いろいろサンプル試したのですが、ことごとくエラーになります
0. どこがいけないのかご教授願います

  1. JSONですが、汎用的にどんな形や項目がきても受取れるプログラミングはできないのでしょうか?

  どれも事前にJSONの項目をクラス定義しとかないといけないサンプルばかりでしたので不便かなと。。。

  1. postData = System.Web.HttpUtility.UrlEncode(json.ToString, enc)の結果がJSONではなく、"xxx.RequestJson3"の文字になってしまう(これがまずNG)

以上、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/01/30 09:11

上手くいく環境があるとのことですが、であればキャプチャツールを利用して要求・応答をキャプチャして、うまくいく場合と行かない場合の違いを比較してみてはいかがですか。それに絶対ヒントがあるはずです。
akiras

2019/01/30 11:06

回答ありがとうございます。 ARCでリクエストするとうまくいくので多分【ソース・リクエスト側】のどこかが間違っていると思われます。 キャプチャツールとはデバックのことでしょうか? ARCはプログラミングではなくリクエストツールなので追うことができないと思います。
退会済みユーザー

退会済みユーザー

2019/01/30 11:29

> キャプチャツールとはデバックのことでしょうか? HTTP 通信の要求・応答をキャプチャするなら Fiddler がお勧めです。ただし、相手が localhost ではダメなので、hosts ファイルで何とかするという対応が必要ですが。
akiras

2019/01/30 13:09

重ね重ね回答ありがとうございます。 明日、Fiddlerで検索して解析してみます。
guest

回答3

0

json.reqdatDataList型とのことですが、それだとToArrayは使えないのではないのですか?
ToArrayが使えるのだとすれば、DataListの配列なのではないでしょうか?
また、json.reqdat.ToArray.ToStringとしたところでJSONデータにはならないのではないですか?

また、UTF-8ではなくSHIFT-JISでエンコードしてバイト配列化しようとしていますが、UTF-8でエンコードしなくてはいけないのではないですか?

追記

JSONへのコンバートですが、NuGetでNewtonsoft.Jsonをインストールし

VB.NET

1 Dim senddata As New RequestJson3 2 3 Dim header As New HeaderList3 4 header.recordNo = "1" 5 header.appVer = "1.0.0" 6 header.houkokuTime = "12:00:00" 7 8 senddata.headerlist3.Add(header) 9 10 Dim data As DataList3 11 data = New DataList3 12 data.recordNo = "11" 13 data.okozukai = "1000" 14 data.actiondate = "2019/01/01" 15 16 senddata.reqdat3.Add(data) 17 18 19 Dim jsondata As String = Newtonsoft.Json.JsonConvert.SerializeObject(senddata) 20 Console.WriteLine(jsondata) 21

でコンバートできます。
このようにコンバート後、UTF-8へのエンコードを行って送信すればいいのではないでしょうか

さらに追記

参照設定にてSystem.Runtime.Serializationを追加し

VB.NET

1 '-------------------------------------------------------------------- 2 ' リクエスト・メインクラス(JSON List) 3 '-------------------------------------------------------------------- 4 <DataContract> 5 Public Class RequestJson3 6 <DataMember> 7 Property headerlist3 As New List(Of HeaderList3) '--- 配列データ  8 <DataMember> 9 Property reqdat3 As New List(Of DataList3) '--- 配列データ  10 End Class 11 12 '-------------------------------------------------------------------- 13 ' リクエスト・ヘッダークラス(List) 14 '-------------------------------------------------------------------- 15 <DataContract> 16 Public Class HeaderList3 17 <DataMember> 18 Property recordNo As String = "" '--- レコード番号 19 <DataMember> 20 Property appVer As String = "" '--- 識別情報 21 <DataMember> 22 Property houkokuTime As String = "" '--- データ作成日時 23 End Class 24 25 '-------------------------------------------------------------------- 26 ' リクエスト・データクラス(List) 27 '-------------------------------------------------------------------- 28 <DataContract> 29 Public Class DataList3 30 <DataMember> 31 Property recordNo As String = "" '--- レコード番号 32 <DataMember> 33 Property okozukai As String = "" '--- お小遣い 34 <DataMember> 35 Property actiondate As String = "" '--- 使った日 36 End Class 37 38 39 ' JSONへシリアライズ 40 Using stream As New MemoryStream 41 Dim serializer = New DataContractJsonSerializer(json.GetType) 42 serializer.WriteObject(stream, json) 43 Console.WriteLine(Encoding.UTF8.GetString(stream.ToArray())) 44 End Using 45

投稿2019/01/30 13:50

編集2019/01/31 02:30
YAmaGNZ

総合スコア10242

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akiras

2019/01/31 01:03

回答ありがとうございます。 もともとやりたかったのが構造体のJSONをリクエストすることなんですが、エラーばかりでてるので配下のDataListだけ切り出して確認していたのですがそれがややこしくなってしまいました。 当たり前ですが postData = System.Web.HttpUtility.UrlEncode(json.ToString, enc) の結果がJSON形式ではなく、"xxx.RequestJson3"の文字になっているのがまずダメなのですが、そのままだとエラーになるのでToStringしました。 上記で実行してもやはり400のエラーです。
akiras

2019/01/31 02:06

詳細情報ありがとうございます。 ・Newtonsoft.Jsonについて、私も見つけたのですがシステムにインストールしていいかの確認が必要なため躊躇していましたがそうも言ってられない状況になってきたので確認してみます ・これから外まわりなので明日試してみます
退会済みユーザー

退会済みユーザー

2019/01/31 02:26

質問 2 は、サーバーから送られてきた JSON 文字列を .NET のオブジェクトに変換するときの話とは違うのですか?
YAmaGNZ

2019/01/31 02:33

現状のサーバへのJSONデータの送信部分のみの回答であり、質問2への回答にはなっていないと思っております。 質問2に関してはどのような状況での話か不明ですので・・・
退会済みユーザー

退会済みユーザー

2019/01/31 03:26

失礼しました。上記は全て質問 1 の範囲での回答であること了解しました。
akiras

2019/02/01 00:08 編集

YAmaGNZさん、SurferOnWwwさん 追加情報ありがとうございます。 同じく別件で割り込み作業が発生してしまいました。 来週また挑戦します!
akiras

2019/02/05 10:39

SurferOnWwwさん、YAmaGNZさん、みなさんのご協力のもと、なんとか動きました! ・Fiddlerをインストールしていろいろリクエストを実行 ・そしてもしかして漢字がいけない?ということで半角のみで実行したら成功(200) ・漢字はどうする?ということで、YAmaGNZさんのDataContractJsonSerializerをヒントにリクエストすることができました お世話になりました。 長い道のりでしたが、なんとか動いてよかったです。
guest

0

自己解決

Private Function RequestToPMS3(ByRef json As RequestJson3) As String

Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("UTF-8") 'POST送信する文字列を作成 Dim postData As String postData = System.Web.HttpUtility.UrlEncode(source, enc) 'バイト型配列に変換 Dim postDataBytes As Byte() = enc.GetBytes(postData) Dim wc As New System.Net.WebClient '--- ヘッダ --- wc.Headers.Add("Content-Type", "application/json; charset=utf-8") Dim eMsg As String = "" Try Dim result As String Using stream As New IO.MemoryStream '▼シリアライズ実行 Dim serializer As New DataContractJsonSerializer(json.GetType) serializer.WriteObject(stream, json) '▼結果を取得 result = System.Text.Encoding.UTF8.GetString(stream.ToArray()) End Using '***** データを送信し、結果を受信する ***** reqCount = reqCount + 1 Dim resData As Byte() '--- これで漢字も送れた Try Dim postDataBytes2 As Byte() = enc.GetBytes(result) resData = wc.UploadData(pmsRequestUrl, postDataBytes2) 'リクエスト Catch ex As Exception End Try wc.Dispose() '受信した結果(JSONデータ)を表示する Dim resText As String = enc.GetString(resData) Return eMsg End Function

投稿2019/02/05 10:31

akiras

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

とりあえず Fiddler の情報を連絡するとともに、答えられるところは答えておきます。

  1. どこがいけないのかご教授願います

まずは、上のコメントでお願いしたように Fiddler などのキャプチャツールを使って、うまくいく場合といかない場合の要求・応答の違いを調べてください。そこにヒントがあるはずです。

ちなみに、HttpWebRequest で JSON 文字列を Web サービスにポスト送信した場合の要求ヘッダとコンテンツ、返ってきた応答ヘッダとコンテンツを Fiddler で見ると以下のようになります。

イメージ説明

HTTP 400 応答 (Bad Request) が返ってきたということは、要求はサーバーまで届いていて、サーバーで受信した要求ヘッダまたはコンテンツの内容が不正だというとこだと思います。そこを注意してうまくいく場合とダメな場合を比較してみると原因が分かるはずです。

参考に、上の Fiddler 画像を撮るのに使った Web サービスと、HttpWebRequest アプリの詳細を書いた記事の URL を書いておきます。興味があれば見てください。

WCF と jQuery AJAX
http://surferonwww.info/BlogEngine/post/2015/10/15/wcf-and-jquery-ajax.aspx

HttpWebRequest で WCF サービスを呼出
http://surferonwww.info/BlogEngine/post/2017/03/26/request-wcf-service-method-by-using-httpwebrequest.aspx

.NET 4.5 から利用できるようになった HttpClient を使ってももちろん可能です。

HttpClient で WCF サービスを呼出
http://surferonwww.info/BlogEngine/post/2018/02/24/request-wcf-service-using-httpclient.aspx

  1. JSONですが、汎用的にどんな形や項目がきても受取れるプログラミングはできないのでしょうか? どれも事前にJSONの項目をクラス定義しとかないといけないサンプルばかりでしたので不便かなと。。。

追記: サーバーから送られてきた JSON 文字列を .NET のオブジェクトに変換するときの話と理解しての回答です。

DynamicJSON を使えば事前の C# でのクラス定義なしでも JSON 文字列を C# のオブジェクトにパースできます。

でも、事前に中身がある程度分からなければ目的の中身を取得するコードは書けないので、意味がないのでは?

質問 3 については後で。

投稿2019/01/31 01:16

編集2019/01/31 03:30
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akiras

2019/01/31 02:01

詳細情報ありがとうございます。 ・.netは4.0なのでHttpClient は使えませんでした ・とりあえずFiddlerをインストールしました  これから外まわりなので明日試してみます
akiras

2019/01/31 23:59

SurferOnWwwさん 追加情報ありがとうございます。 別件で割り込み作業が発生してしまいました。 来週また挑戦します!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問