public StreamMetadata( int?maxCount = null, TimeSpan?maxAge = null, StreamPosition?truncateBefore = null, TimeSpan?cacheControl = null, StreamAcl?acl = null, JsonDocument?customMetadata = null) : this() { if (maxCount <= 0) { throw new ArgumentOutOfRangeException(nameof(maxCount)); } if (maxAge <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(maxAge)); } if (cacheControl <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(cacheControl)); } MaxAge = maxAge; TruncateBefore = truncateBefore; CacheControl = cacheControl; Acl = acl; MaxCount = maxCount; CustomMetadata = customMetadata ?? JsonDocument.Parse("{}"); }
public override List <Version> GetVersions(JsonDocument?contentJSON) { List <Version> allVersions = new(); if (contentJSON is null) { return(allVersions); } JsonElement root = contentJSON.RootElement; try { JsonElement versions = root.GetProperty("releases"); foreach (JsonProperty version in versions.EnumerateObject()) { // TODO: Fails if not a valid semver. ex 0.2 https://github.com/microsoft/OSSGadget/issues/328 allVersions.Add(new Version(version.Name)); } } catch (KeyNotFoundException) { return(allVersions); } catch (InvalidOperationException) { return(allVersions); } return(allVersions); }
/// <summary> /// Gets the asset filename from the Webpack manifest. /// </summary> /// <param name="bundle">The name of the Webpack bundle.</param> /// <returns>The asset filename.</returns> public async Task <string?> GetFromManifestAsync(string bundle) { JsonDocument manifest; if (_manifest == null) { var json = _sharedSettings.DevelopmentMode ? await FetchDevelopmentManifestAsync(HttpClient, _sharedSettings.ManifestPath).ConfigureAwait(false) : await _fileSystem.File.ReadAllTextAsync(_sharedSettings.ManifestPath).ConfigureAwait(false); manifest = JsonDocument.Parse(json); if (!_sharedSettings.DevelopmentMode) { _manifest = manifest; } } else { manifest = _manifest; } try { return(manifest.RootElement.GetProperty(bundle).GetString()); } catch (KeyNotFoundException) { return(null); } }
public DockerComposeParser(string dockerComposeYmlContents) { try { using var reader = new StringReader(dockerComposeYmlContents); var deserializer = new DeserializerBuilder().Build(); var yamlObject = deserializer.Deserialize(reader); if (yamlObject == null) { return; } var serializer = new SerializerBuilder() .JsonCompatible() .Build(); var json = serializer.Serialize(yamlObject); this.dockerComposeModel = JsonDocument.Parse(json); } catch (SyntaxErrorException ex) { throw new DockerComposeSyntaxErrorException(ex); } }
private static async Task <bool> ValidateResponse(HttpResponseMessage response, System.Net.IPAddress newIPAddress) { if (response.StatusCode != System.Net.HttpStatusCode.OK) { Console.WriteLine($"Failed - HTTP status {response.StatusCode}"); Console.WriteLine("Response content: "); Console.WriteLine(await response.Content.ReadAsStringAsync()); Console.WriteLine(); return(false); } try { JsonDocument?doc = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync()); if (doc == null) { throw new Exception("Response content missing"); } var root = doc.RootElement; bool success = root.GetProperty("success").GetBoolean(); if (!success) { Console.WriteLine($"Failed - Errors:"); JsonElement.ArrayEnumerator errors = root.GetProperty("errors").EnumerateArray(); foreach (JsonElement error in errors) { int errorCode = error.GetProperty("code").GetInt32(); string?errorMessage = error.GetProperty("message").GetString(); Console.WriteLine($"{errorCode}: {errorMessage ?? ""}"); } Console.WriteLine(); return(false); } string?resultContent = root.GetProperty("result").GetProperty("content").GetString(); if (!System.Net.IPAddress.TryParse(resultContent, out System.Net.IPAddress? responseIP)) { throw new Exception("IP result contains invalid IP address."); } if (!newIPAddress.Equals(responseIP)) { throw new Exception("Incorrect IP returned"); } Console.WriteLine("Done"); return(true); } catch (Exception e) { Console.WriteLine($"Failed - {e.Message}"); return(false); } }
/// <summary>Attempts to represent the current JSON object as a <see cref="JwtDocument"/>.</summary> /// <param name="value">Receives the value.</param> /// <returns> /// <see langword="true"/> if the JSON object can be represented as a <see cref="JwtDocument"/>, /// <see langword="false"/> otherwise. /// </returns> /// <exception cref="InvalidOperationException"> /// This value's <see cref="ValueKind"/> is not <see cref="JsonValueKind.Object"/>. /// </exception> public bool TryGetJsonDocument([NotNullWhen(true)] out JsonDocument?value) { if (_parent is null) { value = null; return(false); } return(_parent.TryGetValue(_idx, out value)); }
public LogEntry Parse(string?line, LogEntry previousEntry) { if (string.IsNullOrEmpty(line)) { return(LogEntry.Empty); } JsonDocument?json = JsonDocument.Parse(line); if (json == null) { return(LogEntry.Empty); } try { Guid id = Guid.NewGuid(); JsonElement jsonRootElement = json.RootElement; DateTime timestamp = DateTime.Parse(jsonRootElement.GetProperty("@t").GetString() ?? "01.01.1900"); string message = jsonRootElement.GetProperty("@mt").GetString() ?? string.Empty; string sourceContext = jsonRootElement.GetProperty("SourceContext").GetString() ?? string.Empty; string? callerMember = null; if (jsonRootElement.TryGetProperty("CallerMemberName", out JsonElement callerMemberElement)) { callerMember = callerMemberElement.GetString(); } TimeSpan durationSpan = TimeSpan.MinValue; if (jsonRootElement.TryGetProperty("DurationMilliseconds", out JsonElement durationMillisecondsElement)) { if (durationMillisecondsElement.ValueKind == JsonValueKind.Number) { ulong durationMilliseconds = durationMillisecondsElement.GetUInt64(); durationSpan = TimeSpan.FromMilliseconds(durationMilliseconds); } else if (durationMillisecondsElement.ValueKind == JsonValueKind.String) { string?rcDuration = durationMillisecondsElement.GetString(); durationSpan = string.IsNullOrEmpty(rcDuration) ? TimeSpan.MinValue : TimeSpan.Parse(rcDuration); } } if (jsonRootElement.TryGetProperty("RcDuration", out JsonElement rcDurationElement)) { string?rcDuration = rcDurationElement.GetString(); durationSpan = string.IsNullOrEmpty(rcDuration) ? TimeSpan.MinValue : TimeSpan.Parse(rcDuration); } return(new LogEntry(id, previousEntry, timestamp, message, sourceContext, callerMember, durationSpan)); } catch { return(LogEntry.Error); } }
private static byte[] JsonDocumentToByteArray(JsonDocument?document) { if (document == null) { return(Array.Empty <byte>()); } using var stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = false }); document.WriteTo(writer); writer.Flush(); return(stream.ToArray()); }
internal bool TryGetValue(int index, [NotNullWhen(true)] out JsonDocument?value) { JsonRow row = _parsedData.Get(index); ReadOnlySpan <byte> data = _utf8Json.Span; ReadOnlySpan <byte> segment = data.Slice(row.Location, row.Length); var reader = new Utf8JsonReader(segment); if (JsonDocument.TryParseValue(ref reader, out var doc)) { _disposableRegistry.Add(doc); value = doc; return(true); } value = null; return(false); }
protected override async Task Handle(StringBuilder contentBuilder) { var content = await _httpContent !.ReadAsStreamAsync(); JsonDocument?jsonDocument = null; try { jsonDocument = await JsonDocument.ParseAsync(content, new JsonDocumentOptions { AllowTrailingCommas = true }); } catch { // ignored } if (jsonDocument != null) { // write the JsonDocument into a MemoryStream as indented using var stream = new MemoryStream(); var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); jsonDocument.WriteTo(writer); await writer.FlushAsync(); stream.Seek(0, SeekOrigin.Begin); // get the string Json from the MemoryStream using var streamReader = new StreamReader(stream, Encoding.UTF8); var jsonString = await streamReader.ReadToEndAsync(); contentBuilder.Append(jsonString); } else { // append the content as it is if it cannot be parsed as a json contentBuilder.Append(await _httpContent.ReadAsStringAsync()); } }
public async Task GetCurriculum(int id, [FromBody] JsonDocument?request) { if (Request.Headers.GetCommaSeparatedValues("Authorization").ToList().Count < 1) { Response.StatusCode = 403; return; } string token = Request.Headers.GetCommaSeparatedValues("Authorization").ToList().ElementAt(0); if (UserHelpers.GetUser(token, _context).AccessLevel < (int)Permissions.Pupil) { Response.StatusCode = 403; return; } if (_context.Form.FirstOrDefault(row => row.Id == id) == null) { Response.StatusCode = 400; return; } DateTime date = DateTime.Now; JObject jValue = WebMessageHelpers.GetJObjectFromBody(request); if (jValue.ContainsKey("date")) { string strDate = jValue.GetValue("date").ToString(); if (!String.IsNullOrWhiteSpace(strDate)) { date = Convert.ToDateTime(strDate); } } Response.Headers.Add("Access-Control-Allow-Headers", "*"); Response.Headers.Add("Content-Type", "application/json"); byte[] body = CuriculumHelpers.GetHomeWork(_context, id, date); await Response.Body.WriteAsync(body, 0, body.Length); }
public override JsonElement?GetVersionElement(JsonDocument?contentJSON, Version version) { if (contentJSON is null) { return(null); } JsonElement root = contentJSON.RootElement; try { JsonElement versionsJSON = root.GetProperty("versions"); foreach (JsonProperty versionProperty in versionsJSON.EnumerateObject()) { if (versionProperty.Name == version.ToString()) { return(versionsJSON.GetProperty(version.ToString())); } } } catch (KeyNotFoundException) { return(null); } catch (InvalidOperationException) { return(null); } return(null); }
public override List <Version> GetVersions(JsonDocument?contentJSON) { List <Version> allVersions = new List <Version>(); if (contentJSON is null) { return(allVersions); } JsonElement root = contentJSON.RootElement; try { JsonElement versions = root.GetProperty("versions"); foreach (var version in versions.EnumerateObject()) { allVersions.Add(new Version(version.Name)); } } catch (KeyNotFoundException) { return(allVersions); } catch (InvalidOperationException) { return(allVersions); } return(allVersions); }
/// <summary> /// Download one PyPI package and extract it to the target directory. /// </summary> /// <param name="purl">Package URL of the package to download.</param> /// <returns>the path or file written.</returns> public override async Task <IEnumerable <string> > DownloadVersionAsync(PackageURL purl, bool doExtract, bool cached = false) { Logger.Trace("DownloadVersion {0}", purl?.ToString()); string? packageName = purl?.Name; string? packageVersion = purl?.Version; List <string> downloadedPaths = new(); if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion)) { Logger.Debug("Unable to download [{0} {1}]. Both must be defined.", packageName, packageVersion); return(downloadedPaths); } try { HttpClient httpClient = CreateHttpClient(); JsonDocument?doc = await GetJsonCache(httpClient, $"{ENV_PYPI_ENDPOINT}/pypi/{packageName}/json"); if (!doc.RootElement.TryGetProperty("releases", out JsonElement releases)) { return(downloadedPaths); } foreach (JsonProperty versionObject in releases.EnumerateObject()) { if (versionObject.Name != packageVersion) { continue; } foreach (JsonElement release in versionObject.Value.EnumerateArray()) { if (!release.TryGetProperty("packagetype", out JsonElement packageType)) { continue; // Missing a package type } System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(release.GetProperty("url").GetString()); result.EnsureSuccessStatusCode(); string targetName = $"pypi-{packageType}-{packageName}@{packageVersion}"; string extension = ".tar.gz"; if (packageType.ToString() == "bdist_wheel") { extension = ".whl"; } string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName); if (doExtract && Directory.Exists(extractionPath) && cached == true) { downloadedPaths.Add(extractionPath); return(downloadedPaths); } if (doExtract) { downloadedPaths.Add(await ArchiveHelper.ExtractArchiveAsync(TopLevelExtractionDirectory, targetName, await result.Content.ReadAsStreamAsync(), cached)); } else { extractionPath += extension; await File.WriteAllBytesAsync(extractionPath, await result.Content.ReadAsByteArrayAsync()); downloadedPaths.Add(extractionPath); } } } } catch (Exception ex) { Logger.Debug(ex, "Error downloading PyPI package: {0}", ex.Message); } return(downloadedPaths); }
public static bool DeepEquals(this JsonDocument left, JsonDocument?right) { return(DeepEquals(left.RootElement, right?.RootElement)); }
/// <summary> /// Attempts to parse one JSON value (including objects or arrays) from the provided reader. /// </summary> /// <param name="reader">The reader to read.</param> /// <param name="document">Receives the parsed document.</param> /// <returns> /// <see langword="true"/> if a value was read and parsed into a JsonDocument, /// <see langword="false"/> if the reader ran out of data while parsing. /// All other situations result in an exception being thrown. /// </returns> /// <remarks> /// <para> /// If the <see cref="Utf8JsonReader.TokenType"/> property of <paramref name="reader"/> /// is <see cref="JsonTokenType.PropertyName"/> or <see cref="JsonTokenType.None"/>, the /// reader will be advanced by one call to <see cref="Utf8JsonReader.Read"/> to determine /// the start of the value. /// </para> /// /// <para> /// Upon completion of this method, <paramref name="reader"/> will be positioned at the /// final token in the JSON value. If an exception is thrown, or <see langword="false"/> /// is returned, the reader is reset to the state it was in when the method was called. /// </para> /// /// <para> /// This method makes a copy of the data the reader acted on, so there is no caller /// requirement to maintain data integrity beyond the return of this method. /// </para> /// </remarks> /// <exception cref="ArgumentException"> /// <paramref name="reader"/> is using unsupported options. /// </exception> /// <exception cref="ArgumentException"> /// The current <paramref name="reader"/> token does not start or represent a value. /// </exception> /// <exception cref="JsonException"> /// A value could not be read from the reader. /// </exception> public static bool TryParseValue(ref Utf8JsonReader reader, [NotNullWhen(true)] out JsonDocument?document) { return(TryParseValue(ref reader, out document, shouldThrow: false, useArrayPools: true)); }
static PatchElement ReadElement(ref Utf8JsonReader reader) { if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException( $"Expected {nameof(JsonTokenType.StartObject)}"); } // add = 0, remove = 1, replace = 2, copy = 3, move = 4, // test = 5 int? operation = null; JsonPointer? path = null; JsonDocument?value = null; JsonPointer? from = null; while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { break; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException( $"Expected {nameof(JsonTokenType.PropertyName)}"); } if (reader.ValueTextEquals("op")) { if (!reader.Read()) { throw new JsonException(); } if (reader.TokenType != JsonTokenType.String) { throw new JsonException( $"Expected {nameof(JsonTokenType.String)}"); } if (reader.ValueTextEquals("add")) { operation = 0; } else if (reader.ValueTextEquals("remove")) { operation = 1; } else if (reader.ValueTextEquals("replace")) { operation = 2; } else if (reader.ValueTextEquals("copy")) { operation = 3; } else if (reader.ValueTextEquals("move")) { operation = 4; } else if (reader.ValueTextEquals("test")) { operation = 5; } else { throw new JsonException( "The 'op' field must be one of 'add', " + "'remove', 'replace', 'copy', 'move' or " + "'test'."); } } else if (reader.ValueTextEquals("path")) { if (!reader.Read()) { throw new JsonException(); } if (reader.TokenType != JsonTokenType.String) { throw new JsonException( $"Expected {nameof(JsonTokenType.String)}"); } if (!JsonPointer.TryParse(reader.GetString() !, out path)) { throw new JsonException( "Failed to parse JSON Pointer"); } } else if (reader.ValueTextEquals("value")) { if (!JsonDocument.TryParseValue(ref reader, out value)) { throw new JsonException("Failed to parse value"); } } else if (reader.ValueTextEquals("from")) { if (!reader.Read()) { throw new JsonException(); } if (reader.TokenType != JsonTokenType.String) { throw new JsonException( $"Expected {nameof(JsonTokenType.String)}"); } if (!JsonPointer.TryParse(reader.GetString() !, out from)) { throw new JsonException( "Failed to parse JSON Pointer"); } } } return(operation switch { // add 0 => new PatchAddElement(path !, value !), // remove 1 => new PatchRemoveElement(path !), // replace 2 => new PatchReplaceElement(path !, value !), // copy 3 => new PatchCopyElement(path !, from !), // move 4 => new PatchMoveElement(path !, from !), // test 5 => new PatchTestElement(path !, value !), // should never happen since we handle this above _ => null !, });
internal static bool TryParseValue( ref Utf8JsonReader reader, [NotNullWhen(true)] out JsonDocument?document, bool shouldThrow, bool useArrayPools) { JsonReaderState state = reader.CurrentState; CheckSupportedOptions(state.Options, nameof(reader)); // Value copy to overwrite the ref on an exception and undo the destructive reads. Utf8JsonReader restore = reader; ReadOnlySpan <byte> valueSpan = default; ReadOnlySequence <byte> valueSequence = default; try { switch (reader.TokenType) { // A new reader was created and has never been read, // so we need to move to the first token. // (or a reader has terminated and we're about to throw) case JsonTokenType.None: // Using a reader loop the caller has identified a property they wish to // hydrate into a JsonDocument. Move to the value first. case JsonTokenType.PropertyName: { if (!reader.Read()) { if (shouldThrow) { ThrowHelper.ThrowJsonReaderException( ref reader, ExceptionResource.ExpectedJsonTokens); } reader = restore; document = null; return(false); } break; } } switch (reader.TokenType) { // Any of the "value start" states are acceptable. case JsonTokenType.StartObject: case JsonTokenType.StartArray: { long startingOffset = reader.TokenStartIndex; if (!reader.TrySkip()) { if (shouldThrow) { ThrowHelper.ThrowJsonReaderException( ref reader, ExceptionResource.ExpectedJsonTokens); } reader = restore; document = null; return(false); } long totalLength = reader.BytesConsumed - startingOffset; ReadOnlySequence <byte> sequence = reader.OriginalSequence; if (sequence.IsEmpty) { valueSpan = reader.OriginalSpan.Slice( checked ((int)startingOffset), checked ((int)totalLength)); } else { valueSequence = sequence.Slice(startingOffset, totalLength); } Debug.Assert( reader.TokenType == JsonTokenType.EndObject || reader.TokenType == JsonTokenType.EndArray); break; } case JsonTokenType.False: case JsonTokenType.True: case JsonTokenType.Null: if (useArrayPools) { if (reader.HasValueSequence) { valueSequence = reader.ValueSequence; } else { valueSpan = reader.ValueSpan; } break; } document = CreateForLiteral(reader.TokenType); return(true); case JsonTokenType.Number: { if (reader.HasValueSequence) { valueSequence = reader.ValueSequence; } else { valueSpan = reader.ValueSpan; } break; } // String's ValueSequence/ValueSpan omits the quotes, we need them back. case JsonTokenType.String: { ReadOnlySequence <byte> sequence = reader.OriginalSequence; if (sequence.IsEmpty) { // Since the quoted string fit in a ReadOnlySpan originally // the contents length plus the two quotes can't overflow. int payloadLength = reader.ValueSpan.Length + 2; Debug.Assert(payloadLength > 1); ReadOnlySpan <byte> readerSpan = reader.OriginalSpan; Debug.Assert( readerSpan[(int)reader.TokenStartIndex] == (byte)'"', $"Calculated span starts with {readerSpan[(int)reader.TokenStartIndex]}"); Debug.Assert( readerSpan[(int)reader.TokenStartIndex + payloadLength - 1] == (byte)'"', $"Calculated span ends with {readerSpan[(int)reader.TokenStartIndex + payloadLength - 1]}"); valueSpan = readerSpan.Slice((int)reader.TokenStartIndex, payloadLength); } else { long payloadLength = 2; if (reader.HasValueSequence) { payloadLength += reader.ValueSequence.Length; } else { payloadLength += reader.ValueSpan.Length; } valueSequence = sequence.Slice(reader.TokenStartIndex, payloadLength); Debug.Assert( valueSequence.First.Span[0] == (byte)'"', $"Calculated sequence starts with {valueSequence.First.Span[0]}"); Debug.Assert( valueSequence.ToArray()[payloadLength - 1] == (byte)'"', $"Calculated sequence ends with {valueSequence.ToArray()[payloadLength - 1]}"); } break; } default: { if (shouldThrow) { // Default case would only hit if TokenType equals JsonTokenType.EndObject or JsonTokenType.EndArray in which case it would never be sequence Debug.Assert(!reader.HasValueSequence); byte displayByte = reader.ValueSpan[0]; ThrowHelper.ThrowJsonReaderException( ref reader, ExceptionResource.ExpectedStartOfValueNotFound, displayByte); } reader = restore; document = null; return(false); } } } catch { reader = restore; throw; } int length = valueSpan.IsEmpty ? checked ((int)valueSequence.Length) : valueSpan.Length; if (useArrayPools) { byte[] rented = ArrayPool <byte> .Shared.Rent(length); Span <byte> rentedSpan = rented.AsSpan(0, length); try { if (valueSpan.IsEmpty) { valueSequence.CopyTo(rentedSpan); } else { valueSpan.CopyTo(rentedSpan); } document = Parse(rented.AsMemory(0, length), state.Options, rented); } catch { // This really shouldn't happen since the document was already checked // for consistency by Skip. But if data mutations happened just after // the calls to Read then the copy may not be valid. rentedSpan.Clear(); ArrayPool <byte> .Shared.Return(rented); throw; } } else { byte[] owned; if (valueSpan.IsEmpty) { owned = valueSequence.ToArray(); } else { owned = valueSpan.ToArray(); } document = ParseUnrented(owned, state.Options, reader.TokenType); } return(true); }
async public Task handleRequest(HttpContext httpContext) { if (Introspection && httpContext.Request.Path == "/ast.json" && httpContext.Request.Method.ToUpperInvariant() == "GET") { await httpContext.Response.WriteAsync(Api.GetAstJson()); return; } Context? context = null; JsonDocument?bodyDocument = null; var stopWatch = new Stopwatch(); stopWatch.Start(); try { StringValues origin; if (DynamicCorsOrigin && httpContext.Request.Headers.TryGetValue("origin", out origin)) { httpContext.Response.Headers.Add("Access-Control-Allow-Origin", origin); httpContext.Response.Headers.Add("Vary", "Origin"); } string method = httpContext.Request.Method.ToUpperInvariant(); foreach (var header in Headers) { if (method == "OPTIONS" && !header.Key.ToLowerInvariant().StartsWith("access-control-")) { continue; } httpContext.Response.Headers.Add(header.Key, header.Value); } if (method == "OPTIONS") { return; } httpContext.Response.Headers.Add("Content-Type", "application/json; charset=utf-8"); if (method == "HEAD") { return; } if (method == "GET") { if (httpContext.Request.Path.Value != "/") { httpContext.Response.StatusCode = 404; return; } var ok = false; try { ok = await OnHealthCheck(); } catch (Exception) { } httpContext.Response.StatusCode = ok ? 200 : 500; await httpContext.Response.WriteAsync(ok? "{\"ok\":true}" : "{\"ok\":false}"); return; } if (method != "POST") { httpContext.Response.StatusCode = 404; return; } bodyDocument = await JsonDocument.ParseAsync(httpContext.Request.Body); context = ContextParser.DecodeContext(bodyDocument.RootElement, "body"); context.Headers = httpContext.Request.Headers; // TODO: X-Forwarded-For with trusted proxies context.Ip = httpContext.Connection.RemoteIpAddress.ToString(); var duration = stopWatch.Elapsed.TotalSeconds; var bufferWriter = new ArrayBufferWriter <byte>(); using (var resultWriter = new Utf8JsonWriter(bufferWriter)) { resultWriter.WriteStartObject(); resultWriter.WritePropertyName("result"); await Api.ExecuteFunction(context, resultWriter); resultWriter.WriteNull("error"); resultWriter.WriteNumber("duration", duration); resultWriter.WriteString("host", Dns.GetHostName()); resultWriter.WriteEndObject(); } Console.WriteLine($"{context.Id} [{duration.ToString("0.000000")}s] {context.Name}() -> OK"); await httpContext.Response.WriteAsync(Encoding.UTF8.GetString(bufferWriter.WrittenSpan)); } catch (Exception error) { Console.WriteLine(error.ToString()); SdkgenException sdkgenError; if (error is SdkgenException) { sdkgenError = (error as SdkgenException) !; } else { sdkgenError = new SdkgenException("Fatal", error.Message, error); } var duration = stopWatch.Elapsed.TotalSeconds; if (OnRequestError != null && context != null) { OnRequestError.Invoke(context, sdkgenError); Console.WriteLine($"{context.Id} [{duration.ToString("0.000000")}s] {context.Name}() -> {sdkgenError.Type}"); } httpContext.Response.StatusCode = sdkgenError.Type == "Fatal" ? 500 : 400; using (var resultWriter = new Utf8JsonWriter(httpContext.Response.Body)) { resultWriter.WriteStartObject(); resultWriter.WriteNull("result"); resultWriter.WriteStartObject("error"); resultWriter.WriteString("type", sdkgenError.Type); resultWriter.WriteString("message", sdkgenError.Message); resultWriter.WriteEndObject(); resultWriter.WriteNumber("duration", duration); resultWriter.WriteString("host", Dns.GetHostName()); resultWriter.WriteEndObject(); } } finally { bodyDocument?.Dispose(); } }