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

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

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

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

VB.NET

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

Q&A

解決済

3回答

3057閲覧

vb.netで改行、インデントされた JSON 文字列をログに書き込みたい

akiras

総合スコア8

JSON

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

VB.NET

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

0グッド

0クリップ

投稿2019/06/14 02:49

編集2019/06/17 00:05

【やりたいこと】
JSONを構造体のまま、ログに出力したい
JSONを構造体のままログテキストへ出力したいのですが、行き詰っています。
ご教授願います。

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

【ログ出力ソース】 ※My.Application.Logを使用
Sub setErrorLog(jsonEx As ValuesResponse)
- '--- stream
- Dim result As String
- Using stream As New IO.MemoryStream
- Dim serializer As New DataContractJsonSerializer(jsonEx.GetType) '--- シリアライズ
- serializer.WriteObject(stream, jsonEx)
- result = System.Text.Encoding.UTF8.GetString(stream.ToArray()) '--- 結果を取得
- End Using
With My.Application.Log
- .WriteEntry(" ")
- .WriteEntry("★ ○○○システムで障害が発生しました ★")
- .WriteEntry(Format(Now(), "yyyy/MM/dd HH:mm:ss fff"))
- .WriteException(New Exception("・処理ステータス :" & jsonEx.status))
- .WriteException(New Exception("・エラー内容 :" & result))
- .WriteException(New Exception("・エラー内容をJSONの形で出力 :" & resEx.response.ToString))
- End With
End Sub

【ログの結果】
DefaultSource Information 0 ★ ○○○システムで障害が発生しました ★
DefaultSource Information 0 2019/06/14 10:56:10 499
DefaultSource Error 2 ・処理ステータス :1
DefaultSource Error 2 ・エラー内容 :{"version":"1.0","response":[{"recordNm":"11","errorCd":"","errorMsg":""},{"recordNm":"12","errorCd":"ERR-123","errorMsg":"String "aaa12" から型 'Integer' への変換は無効です。 ・・・ データ形式が正しくありません。"}]}
DefaultSource Error 2 ・エラー内容をJSONの形で出力 :System.Collections.Generic.List`1[xxxxx.ResponseList]   ※1

※1 JSONをシリアライズした結果ではなく、JSONの構造体のままログテキストへ出力したいのですが・・・

【欲しい結果:JSONの形で出力】 
{

  • "version": "1.0",
  • "response": [
  • {
  • "recordNm": "11",
  • "errorCd": "",
  • "errorMsg": ""
  • },
  • {
  • "recordNm": "12",
  • "errorCd": "ERR-123",
  • "errorMsg": "String \"aaa12\" から型 'Integer' への変換は無効です。 ・・・ データ形式が正しくありません。"
  • }
  • ]

}

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

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

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

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

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

yoorwm

2019/06/14 03:05

「構造体」「シリアライズ」についてもう少し調べてみると良いのでは?
退会済みユーザー

退会済みユーザー

2019/06/14 03:53

VB.NET のオブジェクトをそのままシリアライズしないでテキストファイルに出力したいということですか? 100% 絶対に不可能とまで言い切る自信はありませんが、それに近いぐらい無理な話と思うのですが。
akiras

2019/06/14 04:15

yoorwm様、SurferOnWww様 ご指摘ありがとうございます。 安易に考えていたのですが、大変だということですね。
退会済みユーザー

退会済みユーザー

2019/06/14 04:33

ひょっとして、VB.NET のオブジェクトを JSON 文字列にシリアライズすると、改行やインデントがされず、連続した長い文字列になってしまう。それを、改行やインデントを入れて読みやすくしたいということですか?
akiras

2019/06/14 05:17

SurferOnWww様 そうです、ログに出力した時にパッと見わかるので。 呼出し元にはJSONで返していますが、こちらのログには見やすい形でログのテキストに出力したいと思って。日時やステータスと一緒にシリアライズしたJSONを改行やインデントで見やすくなればと考えました。
退会済みユーザー

退会済みユーザー

2019/06/14 09:59

そうであればタイトルを書き直していただけませんか? 例えば「改行、インデントされた JSON 文字列をログに書き込みたい」とか。
akiras

2019/06/17 00:03

SurferOnWww様 とりいそぎタイトルを修正します。
guest

回答3

0

コメントに書きましたが、VB.NET のオブジェクトを JSON 文字列にシリアライズすると、改行やインデントがされず、連続した長い文字列になってしまう。それを、改行やインデントを入れて読みやすくしたいということと理解してレスします。

まず、シリアライズする .NET のオブジェクトは以下の RootObject の型でないと質問に書いてあったような形の JSON 文字列にはシリアライズできないのですが、そこのところは OK なのですよね?

public class Response { public string recordNm { get; set; } public string errorCd { get; set; } public string errorMsg { get; set; } } public class RootObject { public string version { get; set; } public List<Response> response { get; set; } }

C# ですが読めますよね? 読めなかったら変換サービスがあるので使ってみてください。

Telerik Code Converter
http://converter.telerik.com/

あと、本筋の話とは直接関係ないですが JSON 文字列から .NET のクラスに変換するのは下記のサービスが便利です。これもコードは C# ですが。

json2csharp
http://json2csharp.com/

ここからが本題ですが、シリアライスする .NET のオブジェクトの型が上記の通り OK であれば、サードバーティ製ですが Newtonsoft.json(Json.NET)の JsonConvert.SerializeObject メソッドに JSON 文字列を改行&インデントして出力するメソッドのオーバーロードがあります。

詳しくは、以下の記事の「JSON形式の文字列をキャメルケースで出力するには?(Json.NET)」のセクションの後半のコードを見てください。

JSONデータを作成/解析するには?[C#/VB]
https://www.atmarkit.co.jp/ait/articles/1709/13/news018.html

JsonConvert.SerializeObject メソッドの第二引数を Formatting.Indented に設定します。

Newtonsoft.json(Json.NET)は NuGet でインストールできます。

イメージ説明

投稿2019/06/14 06:59

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

akiras

2019/06/17 08:03 編集

SurferOnWww様 回答ありがとうございます。 やっと実装できたのですが、なぜかサンプルのようにインデント等してくれません。(各項目に円記号が入ります) ★ソース Imports Newtonsoft.Json Imports Newtonsoft.Json.Serialization ------------------------------ Dim settings = New JsonSerializerSettings With { .ContractResolver = New CamelCasePropertyNamesContractResolver() } ' 出力をインデントするオプション(リリースビルドでは付けない) settings.Formatting = Formatting.Indented 'オプション指定を付けてシリアライズする() Dim output As String = JsonConvert.SerializeObject(result, Formatting.Indented) 'WriteLine(output) With My.Application.Log .WriteEntry(" ") .WriteEntry("   XXXで障害が発生しました ") .WriteEntry(Format(Now(), "yyyy/MM/dd HH:mm:ss fff")) .WriteException(New Exception("・エラー応答内容(シリアライズ) :" & result)) .WriteException(New Exception("・エラー応答内容(キャメルケース) :" & output)) End With ★出力したログ DefaultSource Information 0   XXXで障害が発生しました  DefaultSource Information 0 2019/06/17 16:22:12 470 DefaultSource Error 2 ・エラー応答内容(シリアライズ) :{"version":"1.0",response":[{"recordNm":"-1","errorCd":"ERR-123","errorMsg":"String \"aaa12\" から型 'Integer' への変換は無効です。 ・・・ データ形式が正しくありません。"}]} DefaultSource Error 2 ・エラー応答内容(キャメルケース) :"{\"version\":\"1.0\",\"response\":[\"recordNm\":\"-1\",\"errorCd\":\"ER-123\",\"errorMsg\":\"String \\"aaa12\\" から型 'Integer' への変換は無効です。 ・・・ データ形式が正しくありません。\"}]}"
退会済みユーザー

退会済みユーザー

2019/06/17 22:39 編集

半角の円マーク (フォントによってはバックスラッシュ) は C# の文字列を表す際のエスケープ(意味わかります? 分からなかったらググって調べてください)なのですが、それがどうしてログに書き込むと表示されるのかは分かりません。 一気に全部やらないで、VB.NET のオブジェクトを Newtonsoft.JSON でシリアライズする部分のみ切り出して検証してみてください。 一気に全部やるのはダメです。何が問題か分かり難いので。問題が起こったときは、問題に関係ない部分はどんどん削除して行って、必要最小限のコードで検証するのがお勧めです。
akiras

2019/06/17 23:58

SurferOnWww様 わかりました、あらためて小出しでやってみます。
akiras

2019/06/18 01:24

SurferOnWww様 出来ました。 ストリームに対してシリアライズ/デシリアライズするには?(Json.NET)を参考に実現しました。 ありがとうございました。
guest

0

他の方が指摘されているとおり用語の使い方が色々間違ってる気がしますが…。

JSON形式できれいに整形して出力したい、という意味であればこういうライブラリを使えばいいんじゃないですかね。(いろんな形式で出せますがJSON形式もサポートしてます。)

https://github.com/kbilsted/StatePrinter

投稿2019/06/14 04:06

gentaro

総合スコア8949

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

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

akiras

2019/06/14 04:18

gentaro様 回答ありがとうございます。 これから外出してしまうので、来週じっくり確認させていただきます。 ※少し見たのですがよくわからなかったので
gentaro

2019/06/14 07:39

以下C#の例なんで詳しくはドキュメント読んでほしいですが nugetでStatePrinterを検索して→インストールでプロジェクトに追加したら、 //オブジェクトを作って var printer = new Stateprinter(); //設定して printer.Configuration.SetOutputFormatter(new JsonStyle(printer.Configuration))); //出力対象の適当なオブジェクトを作って var course = new Course(); course.Members.Add(new Student("Stan", course)); course.Members.Add(new Student("Richy", course)); //これで出力 var s = printer.PrintObject(course); Console.WriteLine(s); --こんな出力結果になるはず { "Members" : [ { "name" : "Stan", "course" : root } { "name" : "Richy", "course" : root } ] }
gentaro

2019/06/14 07:40

markdown使えないのでちょっと出力結果が崩れてますが、実際はちゃんとインデントされて出ると思います。
akiras

2019/06/17 07:29

gentaro様 丁重なサンプルありがとうございます。 現在Json.NETで作業中です。
guest

0

自己解決

参考

SurferOnWww様情報の下記URLで『ストリームに対してシリアライズ/デシリアライズするには?(Json.NET)』を参考にしました。
https://www.atmarkit.co.jp/ait/articles/1709/13/news018.html
※みなさん、ありがとうございました!

★ソース

Imports System.Console
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Serialization

Sub setErrorLog(outJson As ValuesResponse) Dim RequestHeaders = WebOperationContext.Current.IncomingRequest.Headers ' リクエストヘッダー Dim serializer = New JsonSerializer() ' オプション指定は、JsonSerializerオブジェクトの各プロパティで行う serializer.ContractResolver = New CamelCasePropertyNamesContractResolver() serializer.Formatting = Formatting.Indented ' レスポンスJSONをシリアライズ(JSONを改行、インデントして出力) Dim output1 As String Using ms = New MemoryStream() Using sw = New StreamWriter(ms) ' 書き込み用のストリームを用意し、 Using writer = New JsonTextWriter(sw) ' JsonTextWriterオブジェクトを作り、 ' JsonSerializerオブジェクトのSerializeメソッドに、 ' JsonTextWriterオブジェクトとシリアライズしたいオブジェクトを渡す serializer.Serialize(writer, outJson) '出力を確認 writer.Flush() output1 = Encoding.UTF8.GetString(ms.ToArray()) ' 既定ではUTF-8で出力 WriteLine(output1) End Using End Using End Using With My.Application.Log .WriteException(New Exception(" ")) .WriteException(New Exception("XXXで障害が発生しました")) .WriteException(New Exception(Format(Now(), "yyyy/MM/dd HH:mm:ss fff"))) .WriteException(New Exception("・エラー応答内容 :" & output1)) .WriteException(New Exception(" ")) End With End Sub

★結果のログ

DefaultSource Error 2
DefaultSource Error 2 XXXで障害が発生しました
DefaultSource Error 2 2019/06/18 10:11:05 910
DefaultSource Error 2 ・エラー応答内容 :{
"version": "1.0",
"response": [
{
"recordNm": "0",
"errorCd": "",
"errorMsg": ""
},
{
"recordNm": "1",
"errorCd": "",
"errorMsg": ""
},
{
"recordNm": "2",
"errorCd": "ER4405",
"errorMsg": "String "2ZZXXXX" から型 'Integer' への変換は無効です。 ・・・ データ形式が正しくありません。"
}
]
}

※実際はちゃんと改行、インデントしています!

投稿2019/06/18 01:29

akiras

総合スコア8

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

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

退会済みユーザー

退会済みユーザー

2019/06/18 01:38

自分が解決した方法を書きたい気持ちは分かりますが、それにたどり着いた回答があるはずで、それをベストアンサーにすべきと思いますけど。 回答がない、もしくは回答があっても役に立たなかったというケースで、自己解決してそれを書いて「解決した方法」マークを付けるならアリだと思いますが。
akiras

2019/06/18 02:50

すいません、ベストアンサーを設定しようと思ったらボタンがなくなってしまったようです。 昨日まではあったと思います。 解決済にしたのがいけなかったのでしょうか・・・
退会済みユーザー

退会済みユーザー

2019/06/18 03:02

次回からよろしくお願いします。
akiras

2019/06/18 03:48

了解です、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問