Skip to content

Commit 18ef7f7

Browse files
authored
[Azure.Core] Adding IJsonModel to ResponseError for AOT compat (Azure#50279)
* adding IJsonModel to ResponseError * exporting API * add tests * refactor tests * add additional test * fix up ResponseError * Update and rename RequestFailedExceptionContext.cs to RequestFailedExceptionSourceGenerationContext.cs * fix parser ref * WIP serialization implementation * ignore concerns and add write per offline convo * copilot added a weird file * fb * fix API * another attempt
1 parent 4f0b5c9 commit 18ef7f7

10 files changed

+652
-122
lines changed

sdk/core/Azure.Core/api/Azure.Core.net462.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,17 @@ protected Response() { }
259259
protected internal abstract bool TryGetHeader(string name, out string? value);
260260
protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable<string>? values);
261261
}
262-
public sealed partial class ResponseError
262+
public sealed partial class ResponseError : System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>, System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>
263263
{
264+
public ResponseError() { }
264265
public ResponseError(string? code, string? message) { }
265266
public string? Code { get { throw null; } }
266267
public string? Message { get { throw null; } }
268+
Azure.ResponseError System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
269+
void System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) { }
270+
Azure.ResponseError System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
271+
string System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
272+
System.BinaryData System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
267273
public override string ToString() { throw null; }
268274
}
269275
public abstract partial class Response<T> : Azure.NullableResponse<T>

sdk/core/Azure.Core/api/Azure.Core.net472.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,17 @@ protected Response() { }
259259
protected internal abstract bool TryGetHeader(string name, out string? value);
260260
protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable<string>? values);
261261
}
262-
public sealed partial class ResponseError
262+
public sealed partial class ResponseError : System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>, System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>
263263
{
264+
public ResponseError() { }
264265
public ResponseError(string? code, string? message) { }
265266
public string? Code { get { throw null; } }
266267
public string? Message { get { throw null; } }
268+
Azure.ResponseError System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
269+
void System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) { }
270+
Azure.ResponseError System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
271+
string System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
272+
System.BinaryData System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
267273
public override string ToString() { throw null; }
268274
}
269275
public abstract partial class Response<T> : Azure.NullableResponse<T>

sdk/core/Azure.Core/api/Azure.Core.net6.0.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,17 @@ protected Response() { }
259259
protected internal abstract bool TryGetHeader(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value);
260260
protected internal abstract bool TryGetHeaderValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable<string>? values);
261261
}
262-
public sealed partial class ResponseError
262+
public sealed partial class ResponseError : System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>, System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>
263263
{
264+
public ResponseError() { }
264265
public ResponseError(string? code, string? message) { }
265266
public string? Code { get { throw null; } }
266267
public string? Message { get { throw null; } }
268+
Azure.ResponseError System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
269+
void System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) { }
270+
Azure.ResponseError System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
271+
string System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
272+
System.BinaryData System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
267273
public override string ToString() { throw null; }
268274
}
269275
public abstract partial class Response<T> : Azure.NullableResponse<T>

sdk/core/Azure.Core/api/Azure.Core.net8.0.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,11 +266,17 @@ protected Response() { }
266266
protected internal abstract bool TryGetHeader(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out string? value);
267267
protected internal abstract bool TryGetHeaderValues(string name, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IEnumerable<string>? values);
268268
}
269-
public sealed partial class ResponseError
269+
public sealed partial class ResponseError : System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>, System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>
270270
{
271+
public ResponseError() { }
271272
public ResponseError(string? code, string? message) { }
272273
public string? Code { get { throw null; } }
273274
public string? Message { get { throw null; } }
275+
Azure.ResponseError System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
276+
void System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) { }
277+
Azure.ResponseError System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
278+
string System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
279+
System.BinaryData System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
274280
public override string ToString() { throw null; }
275281
}
276282
public abstract partial class Response<T> : Azure.NullableResponse<T>

sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,17 @@ protected Response() { }
259259
protected internal abstract bool TryGetHeader(string name, out string? value);
260260
protected internal abstract bool TryGetHeaderValues(string name, out System.Collections.Generic.IEnumerable<string>? values);
261261
}
262-
public sealed partial class ResponseError
262+
public sealed partial class ResponseError : System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>, System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>
263263
{
264+
public ResponseError() { }
264265
public ResponseError(string? code, string? message) { }
265266
public string? Code { get { throw null; } }
266267
public string? Message { get { throw null; } }
268+
Azure.ResponseError System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Create(ref System.Text.Json.Utf8JsonReader reader, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
269+
void System.ClientModel.Primitives.IJsonModel<Azure.ResponseError>.Write(System.Text.Json.Utf8JsonWriter writer, System.ClientModel.Primitives.ModelReaderWriterOptions options) { }
270+
Azure.ResponseError System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Create(System.BinaryData data, System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
271+
string System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.GetFormatFromOptions(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
272+
System.BinaryData System.ClientModel.Primitives.IPersistableModel<Azure.ResponseError>.Write(System.ClientModel.Primitives.ModelReaderWriterOptions options) { throw null; }
267273
public override string ToString() { throw null; }
268274
}
269275
public abstract partial class Response<T> : Azure.NullableResponse<T>
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.ClientModel.Primitives;
6+
using System.Collections.Generic;
7+
using System.Globalization;
8+
using System.Text;
9+
using System.Text.Json;
10+
using System.Text.Json.Serialization;
11+
using Azure.Core;
12+
13+
namespace Azure
14+
{
15+
/// <summary>
16+
/// Represents an error returned by an Azure Service.
17+
/// </summary>
18+
[JsonConverter(typeof(Converter))]
19+
[TypeReferenceType(true, [nameof(Target), nameof(Details)])]
20+
public sealed partial class ResponseError : IJsonModel<ResponseError>
21+
{
22+
// This class needs to be internal rather than private so that it can be used by the System.Text.Json source generator
23+
internal class Converter : JsonConverter<ResponseError?>
24+
{
25+
public override ResponseError? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
26+
{
27+
using var document = JsonDocument.ParseValue(ref reader);
28+
var element = document.RootElement;
29+
return ReadFromJson(element);
30+
}
31+
32+
public override void Write(Utf8JsonWriter writer, ResponseError? value, JsonSerializerOptions options)
33+
{
34+
throw new NotImplementedException();
35+
}
36+
}
37+
38+
/// <summary>
39+
/// Writes the <see cref="ResponseError"/> to the provided <see cref="Utf8JsonWriter"/>.
40+
/// </summary>
41+
private void Write(Utf8JsonWriter writer)
42+
{
43+
writer.WriteStartObject();
44+
45+
if (Code != null)
46+
{
47+
writer.WritePropertyName("code");
48+
writer.WriteStringValue(Code);
49+
}
50+
51+
if (Message != null)
52+
{
53+
writer.WritePropertyName("message");
54+
writer.WriteStringValue(Message);
55+
}
56+
57+
if (Target != null)
58+
{
59+
writer.WritePropertyName("target");
60+
writer.WriteStringValue(Target);
61+
}
62+
63+
if (InnerError != null)
64+
{
65+
writer.WritePropertyName("innererror");
66+
InnerError.Write(writer, ModelReaderWriterOptions.Json);
67+
}
68+
69+
if (Details.Count > 0)
70+
{
71+
writer.WritePropertyName("details");
72+
writer.WriteStartArray();
73+
74+
foreach (var detail in Details)
75+
{
76+
if (detail == null)
77+
{
78+
writer.WriteNullValue();
79+
}
80+
else
81+
{
82+
detail.Write(writer);
83+
}
84+
}
85+
86+
writer.WriteEndArray();
87+
}
88+
89+
writer.WriteEndObject();
90+
}
91+
92+
private static ResponseError? ReadFromJson(JsonElement element)
93+
{
94+
if (element.ValueKind == JsonValueKind.Null)
95+
{
96+
return null;
97+
}
98+
99+
string? code = null;
100+
if (element.TryGetProperty("code", out var property))
101+
{
102+
code = property.GetString();
103+
}
104+
105+
string? message = null;
106+
if (element.TryGetProperty("message", out property))
107+
{
108+
message = property.GetString();
109+
}
110+
111+
string? target = null;
112+
if (element.TryGetProperty("target", out property))
113+
{
114+
target = property.GetString();
115+
}
116+
117+
ResponseInnerError? innererror = null;
118+
if (element.TryGetProperty("innererror", out property))
119+
{
120+
innererror = ResponseInnerError.ReadFromJson(property);
121+
}
122+
123+
List<ResponseError>? details = null;
124+
if (element.TryGetProperty("details", out property) &&
125+
property.ValueKind == JsonValueKind.Array)
126+
{
127+
foreach (var item in property.EnumerateArray())
128+
{
129+
var detail = ReadFromJson(item);
130+
if (detail != null)
131+
{
132+
details ??= new();
133+
details.Add(detail);
134+
}
135+
}
136+
}
137+
138+
return new ResponseError(code, message, target, element.Clone(), innererror, details);
139+
}
140+
141+
void IJsonModel<ResponseError>.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
142+
{
143+
var format = options.Format == "W" ? ((IPersistableModel<ResponseError>)this).GetFormatFromOptions(options) : options.Format;
144+
if (format != "J")
145+
{
146+
throw new FormatException($"The model {nameof(ResponseError)} does not support '{format}' format.");
147+
}
148+
149+
writer.WriteStartObject();
150+
151+
if (Code != null)
152+
{
153+
writer.WritePropertyName("code");
154+
writer.WriteStringValue(Code);
155+
}
156+
157+
if (Message != null)
158+
{
159+
writer.WritePropertyName("message");
160+
writer.WriteStringValue(Message);
161+
}
162+
163+
if (Target != null)
164+
{
165+
writer.WritePropertyName("target");
166+
writer.WriteStringValue(Target);
167+
}
168+
169+
if (InnerError != null)
170+
{
171+
writer.WritePropertyName("innererror");
172+
InnerError.Write(writer, ModelReaderWriterOptions.Json);
173+
}
174+
175+
if (Details.Count > 0)
176+
{
177+
writer.WritePropertyName("details");
178+
writer.WriteStartArray();
179+
180+
foreach (var detail in Details)
181+
{
182+
if (detail == null)
183+
{
184+
writer.WriteNullValue();
185+
}
186+
else
187+
{
188+
detail.Write(writer);
189+
}
190+
}
191+
192+
writer.WriteEndArray();
193+
}
194+
195+
writer.WriteEndObject();
196+
}
197+
198+
ResponseError IJsonModel<ResponseError>.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
199+
{
200+
var format = options.Format == "W" ? ((IPersistableModel<ResponseError>)this).GetFormatFromOptions(options) : options.Format;
201+
if (format != "J")
202+
{
203+
throw new FormatException($"The model {nameof(ResponseError)} does not support '{format}' format.");
204+
}
205+
206+
using var document = JsonDocument.ParseValue(ref reader);
207+
var element = document.RootElement;
208+
return ReadFromJson(element) ?? new ResponseError();
209+
}
210+
211+
BinaryData IPersistableModel<ResponseError>.Write(ModelReaderWriterOptions options)
212+
{
213+
var format = options.Format == "W" ? ((IPersistableModel<ResponseError>)this).GetFormatFromOptions(options) : options.Format;
214+
if (format != "J")
215+
{
216+
throw new FormatException($"The model {nameof(ResponseError)} does not support '{format}' format.");
217+
}
218+
219+
return ModelReaderWriter.Write(this, options, AzureCoreContext.Default);
220+
}
221+
222+
ResponseError IPersistableModel<ResponseError>.Create(BinaryData data, ModelReaderWriterOptions options)
223+
{
224+
var format = options.Format == "W" ? ((IPersistableModel<ResponseError>)this).GetFormatFromOptions(options) : options.Format;
225+
if (format != "J")
226+
{
227+
throw new FormatException($"The model {nameof(ResponseError)} does not support '{format}' format.");
228+
}
229+
230+
using var document = JsonDocument.Parse(data);
231+
var element = document.RootElement;
232+
return ReadFromJson(element) ?? new ResponseError();
233+
}
234+
235+
string IPersistableModel<ResponseError>.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
236+
}
237+
}

0 commit comments

Comments
 (0)