回答編集履歴

2

見直しキャンペーン中

2023/07/26 13:08

投稿

TN8001
TN8001

スコア9862

test CHANGED
@@ -1,349 +1,175 @@
1
1
  解決されたようですが気になったので調査しました。
2
-
3
2
  `JsonConverter`を書けば何とかなりました。動いてはいますが正しいかはわかりません^^;
4
3
 
5
-
6
-
7
- ```C#
4
+ ```cs
8
-
9
5
  using Newtonsoft.Json;
10
-
11
6
  using Newtonsoft.Json.Linq;
12
-
13
7
  using System;
14
-
15
8
  using System.Linq;
16
9
 
17
-
18
-
19
10
  namespace Questions315978
20
-
21
11
  {
22
-
23
12
  class Program
24
-
25
13
  {
26
-
27
14
  static void Main()
28
-
29
15
  {
30
-
31
16
  var errorJson = @"
32
-
33
17
  [
34
-
35
18
  {
36
-
37
19
  ""error_code"": ""E01"",
38
-
39
20
  ""error_information"": ""hogehoge""
40
-
41
21
  },
42
-
43
22
  {
44
-
45
23
  ""error_code"": ""E02"",
46
-
47
24
  ""error_information"": ""mogemoge""
48
-
49
25
  }
50
-
51
26
  ]".Trim();
52
-
53
27
  //var r0 = JsonConvert.DeserializeObject<Response.Error[]>(errorJson);
54
-
55
28
  var r1 = JsonConvert.DeserializeObject<HogeApiResponse>(errorJson);
56
29
 
57
30
 
31
+ var successJson = @"
32
+ {
33
+ ""token"": ""abcdefghijklmnopqrstuvwxyz""
34
+ }".Trim();
35
+ var r2 = JsonConvert.DeserializeObject<HogeApiResponse>(successJson);
36
+ }
37
+ }
58
38
 
39
+ public class ResponseJsonConverter : JsonConverter
40
+ {
41
+ public override bool CanConvert(Type objectType)
42
+ => typeof(Response).IsAssignableFrom(objectType);
43
+
44
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
45
+ {
46
+ if (reader.TokenType == JsonToken.StartArray)
47
+ {
48
+ var jArray = JArray.Load(reader);
49
+ var target = (Response)Activator.CreateInstance(objectType);
50
+ target.Errors = jArray.Select(x => JsonConvert.DeserializeObject<Response.Error>(x.ToString())).ToArray();
51
+ return target;
52
+ }
53
+ else
54
+ {
55
+ var jObject = JObject.Load(reader);
56
+ var target = Activator.CreateInstance(objectType);
57
+ serializer.Populate(jObject.CreateReader(), target);
58
+ return target;
59
+ }
60
+ }
61
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
62
+ => throw new NotImplementedException();
63
+ }
64
+
65
+ [JsonConverter(typeof(ResponseJsonConverter))]
66
+ public abstract class Response
67
+ {
68
+ public Error[] Errors { get; set; }
69
+
70
+ public class Error
71
+ {
72
+ [JsonProperty("error_code")]
73
+ public string ErrorCode { get; set; }
74
+
75
+ [JsonProperty("error_information")]
76
+ public string ErrorInformation { get; set; }
77
+ }
78
+ }
79
+
80
+ public class HogeApiResponse : Response
81
+ {
82
+ [JsonProperty("token")]
83
+ public string Token { get; set; }
84
+ }
85
+ }
86
+ ```
87
+
88
+ ---
89
+
90
+ ついでに`System.Text.Json`版もやってみたのですが、さらに自信ありません^^;
91
+
92
+ ```cs
93
+ using System;
94
+ using System.Text.Json;
95
+ using System.Text.Json.Serialization;
96
+
97
+ namespace Questions315978
98
+ {
99
+ class Program
100
+ {
101
+ static void Main()
102
+ {
103
+ var errorJson = @"
104
+ [
105
+ {
106
+ ""error_code"": ""E01"",
107
+ ""error_information"": ""hogehoge""
108
+ },
109
+ {
110
+ ""error_code"": ""E02"",
111
+ ""error_information"": ""mogemoge""
112
+ }
113
+ ]".Trim();
114
+ var options = new JsonSerializerOptions();
115
+ options.Converters.Add(new ResponseJsonConverter());
116
+ //var r0 = JsonSerializer.Deserialize<Response.Error[]>(errorJson);
117
+ var r1 = JsonSerializer.Deserialize<HogeApiResponse>(errorJson, options);
59
118
 
60
119
 
61
120
  var successJson = @"
62
-
63
121
  {
64
-
65
122
  ""token"": ""abcdefghijklmnopqrstuvwxyz""
66
-
67
123
  }".Trim();
68
-
69
- var r2 = JsonConvert.DeserializeObject<HogeApiResponse>(successJson);
124
+ var r2 = JsonSerializer.Deserialize<HogeApiResponse>(successJson, options);
70
-
71
125
  }
72
-
73
126
  }
74
127
 
128
+ public class ResponseJsonConverter : JsonConverter<Response>
129
+ {
130
+ public override bool CanConvert(Type typeToConvert)
131
+ => typeof(Response).IsAssignableFrom(typeToConvert);
75
132
 
76
-
77
- public class ResponseJsonConverter : JsonConverter
78
-
79
- {
80
-
81
- public override bool CanConvert(Type objectType)
82
-
83
- => typeof(Response).IsAssignableFrom(objectType);
84
-
85
-
86
-
87
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
133
+ public override Response Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
88
-
89
134
  {
90
-
91
- if (reader.TokenType == JsonToken.StartArray)
135
+ if (reader.TokenType == JsonTokenType.StartArray)
92
-
93
136
  {
94
-
95
- var jArray = JArray.Load(reader);
96
-
97
- var target = (Response)Activator.CreateInstance(objectType);
137
+ var target = (Response)Activator.CreateInstance(typeToConvert);
98
-
99
- target.Errors = jArray.Select(x => JsonConvert.DeserializeObject<Response.Error>(x.ToString())).ToArray();
138
+ target.Errors = JsonSerializer.Deserialize<Response.Error[]>(ref reader);
100
-
101
139
  return target;
102
-
103
140
  }
104
-
105
141
  else
106
-
107
142
  {
108
-
109
- var jObject = JObject.Load(reader);
110
-
111
- var target = Activator.CreateInstance(objectType);
143
+ // options渡すと当然StackOverflowException
112
-
113
- serializer.Populate(jObject.CreateReader(), target);
144
+ return (Response)JsonSerializer.Deserialize(ref reader, typeToConvert);
114
-
115
- return target;
116
-
117
145
  }
118
-
119
146
  }
120
-
121
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
147
+ public override void Write(Utf8JsonWriter writer, Response value, JsonSerializerOptions options)
122
-
123
148
  => throw new NotImplementedException();
124
-
125
149
  }
126
150
 
127
-
151
+ // こうも書けるのだが派生に引き継がれないっぽいのと、
128
-
152
+ // 優先度が高すぎてStackOverflowExceptionを抑えられない^^;
129
- [JsonConverter(typeof(ResponseJsonConverter))]
153
+ //[JsonConverter(typeof(ResponseJsonConverter))] // ダメ!
130
-
131
154
  public abstract class Response
132
-
133
155
  {
134
-
135
156
  public Error[] Errors { get; set; }
136
157
 
137
-
138
-
139
158
  public class Error
140
-
141
159
  {
142
-
143
- [JsonProperty("error_code")]
160
+ [JsonPropertyName("error_code")]
144
-
145
161
  public string ErrorCode { get; set; }
146
162
 
147
-
148
-
149
- [JsonProperty("error_information")]
163
+ [JsonPropertyName("error_information")]
150
-
151
164
  public string ErrorInformation { get; set; }
152
-
153
165
  }
154
-
155
166
  }
156
167
 
157
-
168
+ //[JsonConverter(typeof(ResponseJsonConverter))] // ダメ!
158
-
159
169
  public class HogeApiResponse : Response
160
-
161
170
  {
162
-
163
- [JsonProperty("token")]
171
+ [JsonPropertyName("token")]
164
-
165
172
  public string Token { get; set; }
166
-
167
173
  }
168
-
169
174
  }
170
-
171
175
  ```
172
-
173
-
174
-
175
- ---
176
-
177
-
178
-
179
- ついでに`System.Text.Json`版もやってみたのですが、さらに自信ありません^^;
180
-
181
-
182
-
183
- ```C#
184
-
185
- using System;
186
-
187
- using System.Text.Json;
188
-
189
- using System.Text.Json.Serialization;
190
-
191
-
192
-
193
- namespace Questions315978
194
-
195
- {
196
-
197
- class Program
198
-
199
- {
200
-
201
- static void Main()
202
-
203
- {
204
-
205
- var errorJson = @"
206
-
207
- [
208
-
209
- {
210
-
211
- ""error_code"": ""E01"",
212
-
213
- ""error_information"": ""hogehoge""
214
-
215
- },
216
-
217
- {
218
-
219
- ""error_code"": ""E02"",
220
-
221
- ""error_information"": ""mogemoge""
222
-
223
- }
224
-
225
- ]".Trim();
226
-
227
- var options = new JsonSerializerOptions();
228
-
229
- options.Converters.Add(new ResponseJsonConverter());
230
-
231
- //var r0 = JsonSerializer.Deserialize<Response.Error[]>(errorJson);
232
-
233
- var r1 = JsonSerializer.Deserialize<HogeApiResponse>(errorJson, options);
234
-
235
-
236
-
237
-
238
-
239
- var successJson = @"
240
-
241
- {
242
-
243
- ""token"": ""abcdefghijklmnopqrstuvwxyz""
244
-
245
- }".Trim();
246
-
247
- var r2 = JsonSerializer.Deserialize<HogeApiResponse>(successJson, options);
248
-
249
- }
250
-
251
- }
252
-
253
-
254
-
255
- public class ResponseJsonConverter : JsonConverter<Response>
256
-
257
- {
258
-
259
- public override bool CanConvert(Type typeToConvert)
260
-
261
- => typeof(Response).IsAssignableFrom(typeToConvert);
262
-
263
-
264
-
265
- public override Response Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
266
-
267
- {
268
-
269
- if (reader.TokenType == JsonTokenType.StartArray)
270
-
271
- {
272
-
273
- var target = (Response)Activator.CreateInstance(typeToConvert);
274
-
275
- target.Errors = JsonSerializer.Deserialize<Response.Error[]>(ref reader);
276
-
277
- return target;
278
-
279
- }
280
-
281
- else
282
-
283
- {
284
-
285
- // options渡すと当然StackOverflowException
286
-
287
- return (Response)JsonSerializer.Deserialize(ref reader, typeToConvert);
288
-
289
- }
290
-
291
- }
292
-
293
- public override void Write(Utf8JsonWriter writer, Response value, JsonSerializerOptions options)
294
-
295
- => throw new NotImplementedException();
296
-
297
- }
298
-
299
-
300
-
301
- // こうも書けるのだが派生に引き継がれないっぽいのと、
302
-
303
- // 優先度が高すぎてStackOverflowExceptionを抑えられない^^;
304
-
305
- //[JsonConverter(typeof(ResponseJsonConverter))] // ダメ!
306
-
307
- public abstract class Response
308
-
309
- {
310
-
311
- public Error[] Errors { get; set; }
312
-
313
-
314
-
315
- public class Error
316
-
317
- {
318
-
319
- [JsonPropertyName("error_code")]
320
-
321
- public string ErrorCode { get; set; }
322
-
323
-
324
-
325
- [JsonPropertyName("error_information")]
326
-
327
- public string ErrorInformation { get; set; }
328
-
329
- }
330
-
331
- }
332
-
333
-
334
-
335
- //[JsonConverter(typeof(ResponseJsonConverter))] // ダメ!
336
-
337
- public class HogeApiResponse : Response
338
-
339
- {
340
-
341
- [JsonPropertyName("token")]
342
-
343
- public string Token { get; set; }
344
-
345
- }
346
-
347
- }
348
-
349
- ```

1

internal

2021/01/15 16:20

投稿

TN8001
TN8001

スコア9862

test CHANGED
@@ -194,11 +194,11 @@
194
194
 
195
195
  {
196
196
 
197
- internal class Program
197
+ class Program
198
-
198
+
199
- {
199
+ {
200
-
200
+
201
- private static void Main()
201
+ static void Main()
202
202
 
203
203
  {
204
204