diff --git a/dotnet/src/webdriver/Response.cs b/dotnet/src/webdriver/Response.cs
index 133d82af1619d..8f643e7082809 100644
--- a/dotnet/src/webdriver/Response.cs
+++ b/dotnet/src/webdriver/Response.cs
@@ -19,10 +19,10 @@
using OpenQA.Selenium.Internal;
using System;
-using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text.Json;
+using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
#nullable enable
@@ -30,16 +30,10 @@
namespace OpenQA.Selenium
{
///
- /// Handles reponses from the browser
+ /// Handles responses from the browser
///
public class Response
{
- private static readonly JsonSerializerOptions s_jsonSerializerOptions = new()
- {
- TypeInfoResolver = ResponseJsonSerializerContext.Default,
- Converters = { new ResponseValueJsonConverter() } // we still need it to make `Object` as `Dictionary`
- };
-
///
/// Initializes a new instance of the class
///
@@ -62,18 +56,18 @@ public Response(string? sessionId, object? value, WebDriverResult status)
/// If is not a valid JSON object.
public static Response FromJson(string value)
{
- Dictionary rawResponse = JsonSerializer.Deserialize>(value, s_jsonSerializerOptions)
- ?? throw new WebDriverException("JSON success response returned \"null\" value");
+ JsonObject rawResponse = JsonNode.Parse(value) as JsonObject
+ ?? throw new WebDriverException($"JSON success response did not return a dictionary{Environment.NewLine}{value}");
- object? contents;
+ JsonNode? contents;
string? sessionId = null;
- if (rawResponse.TryGetValue("sessionId", out object? s) && s is not null)
+ if (rawResponse.TryGetPropertyValue("sessionId", out JsonNode? s) && s is not null)
{
sessionId = s.ToString();
}
- if (rawResponse.TryGetValue("value", out object? valueObj))
+ if (rawResponse.TryGetPropertyValue("value", out JsonNode? valueObj))
{
contents = valueObj;
}
@@ -87,7 +81,7 @@ public static Response FromJson(string value)
// Special-case for the new session command, where the "capabilities"
// property of the response is the actual value we're interested in.
- if (rawResponse.TryGetValue("capabilities", out object? capabilities))
+ if (rawResponse.TryGetPropertyValue("capabilities", out JsonNode? capabilities))
{
contents = capabilities;
}
@@ -97,14 +91,14 @@ public static Response FromJson(string value)
}
}
- if (contents is Dictionary valueDictionary)
+ if (contents is JsonObject valueDictionary)
{
// Special case code for the new session command. If the response contains
// sessionId and capabilities properties, fix up the session ID and value members.
- if (valueDictionary.TryGetValue("sessionId", out object? session))
+ if (valueDictionary.TryGetPropertyValue("sessionId", out JsonNode? session))
{
- sessionId = session.ToString();
- if (valueDictionary.TryGetValue("capabilities", out object? capabilities))
+ sessionId = session?.ToString();
+ if (valueDictionary.TryGetPropertyValue("capabilities", out JsonNode? capabilities))
{
contents = capabilities;
}
@@ -115,7 +109,9 @@ public static Response FromJson(string value)
}
}
- return new Response(sessionId, contents, WebDriverResult.Success);
+ var contentsDictionary = JsonSerializer.Deserialize(contents, ResponseJsonSerializerContext.Default.Object);
+
+ return new Response(sessionId, contentsDictionary, WebDriverResult.Success);
}
///
@@ -143,29 +139,30 @@ public static Response FromJson(string value)
/// If the JSON dictionary is not in the expected state, per spec.
public static Response FromErrorJson(string value)
{
- Dictionary deserializedResponse = JsonSerializer.Deserialize>(value, s_jsonSerializerOptions)
- ?? throw new WebDriverException("JSON error response returned \"null\" value");
+ JsonObject responseObject = JsonNode.Parse(value) as JsonObject
+ ?? throw new WebDriverException($"JSON error response did not return an object{Environment.NewLine}{value}");
- if (!deserializedResponse.TryGetValue("value", out object? valueObject))
+ if (!responseObject.TryGetPropertyValue("value", out JsonNode? valueNode))
{
- throw new WebDriverException($"The 'value' property was not found in the response:{Environment.NewLine}{value}");
+ throw new WebDriverException($"The 'value' property was not found in the response{Environment.NewLine}{value}");
}
- if (valueObject is not Dictionary valueDictionary)
+ if (valueNode is not JsonObject valueObject)
{
- throw new WebDriverException($"The 'value' property is not a dictionary of {Environment.NewLine}{value}");
+ throw new WebDriverException($"The 'value' property is not a dictionary{Environment.NewLine}{value}");
}
- if (!valueDictionary.TryGetValue("error", out object? errorObject))
+ if (!valueObject.TryGetPropertyValue("error", out JsonNode? errorObject))
{
- throw new WebDriverException($"The 'value > error' property was not found in the response:{Environment.NewLine}{value}");
+ throw new WebDriverException($"The 'value > error' property was not found in the response{Environment.NewLine}{value}");
}
- if (errorObject is not string errorString)
+ if (errorObject is not JsonValue errorValue || !errorValue.TryGetValue(out string? errorString))
{
throw new WebDriverException($"The 'value > error' property is not a string{Environment.NewLine}{value}");
}
+ var valueDictionary = JsonSerializer.Deserialize(valueObject, ResponseJsonSerializerContext.Default.Object);
WebDriverResult status = WebDriverError.ResultFromError(errorString);
return new Response(sessionId: null, valueDictionary, status);
@@ -205,6 +202,7 @@ public override string ToString()
}
}
- [JsonSerializable(typeof(Dictionary))]
+ [JsonSerializable(typeof(object))]
+ [JsonSourceGenerationOptions(Converters = [typeof(ResponseValueJsonConverter)])] // we still need it to make `Object` as `Dictionary`
internal sealed partial class ResponseJsonSerializerContext : JsonSerializerContext;
}