1919
2020using OpenQA . Selenium . Internal ;
2121using System ;
22- using System . Collections . Generic ;
2322using System . Diagnostics . CodeAnalysis ;
2423using System . Globalization ;
2524using System . Text . Json ;
25+ using System . Text . Json . Nodes ;
2626using System . Text . Json . Serialization ;
2727
2828#nullable enable
2929
3030namespace OpenQA . Selenium
3131{
3232 /// <summary>
33- /// Handles reponses from the browser
33+ /// Handles responses from the browser
3434 /// </summary>
3535 public class Response
3636 {
37- private static readonly JsonSerializerOptions s_jsonSerializerOptions = new ( )
38- {
39- TypeInfoResolver = ResponseJsonSerializerContext . Default ,
40- Converters = { new ResponseValueJsonConverter ( ) } // we still need it to make `Object` as `Dictionary`
41- } ;
42-
4337 /// <summary>
4438 /// Initializes a new instance of the <see cref="Response"/> class
4539 /// </summary>
@@ -62,18 +56,18 @@ public Response(string? sessionId, object? value, WebDriverResult status)
6256 /// <exception cref="JsonException">If <paramref name="value"/> is not a valid JSON object.</exception>
6357 public static Response FromJson ( string value )
6458 {
65- Dictionary < string , object ? > rawResponse = JsonSerializer . Deserialize < Dictionary < string , object ? > > ( value , s_jsonSerializerOptions )
66- ?? throw new WebDriverException ( "JSON success response returned \" null \" value" ) ;
59+ JsonObject rawResponse = JsonNode . Parse ( value ) as JsonObject
60+ ?? throw new WebDriverException ( $ "JSON success response did not return a dictionary { Environment . NewLine } { value } ") ;
6761
68- object ? contents ;
62+ JsonNode ? contents ;
6963 string ? sessionId = null ;
7064
71- if ( rawResponse . TryGetValue ( "sessionId" , out object ? s ) && s is not null )
65+ if ( rawResponse . TryGetPropertyValue ( "sessionId" , out JsonNode ? s ) && s is not null )
7266 {
7367 sessionId = s . ToString ( ) ;
7468 }
7569
76- if ( rawResponse . TryGetValue ( "value" , out object ? valueObj ) )
70+ if ( rawResponse . TryGetPropertyValue ( "value" , out JsonNode ? valueObj ) )
7771 {
7872 contents = valueObj ;
7973 }
@@ -87,7 +81,7 @@ public static Response FromJson(string value)
8781
8882 // Special-case for the new session command, where the "capabilities"
8983 // property of the response is the actual value we're interested in.
90- if ( rawResponse . TryGetValue ( "capabilities" , out object ? capabilities ) )
84+ if ( rawResponse . TryGetPropertyValue ( "capabilities" , out JsonNode ? capabilities ) )
9185 {
9286 contents = capabilities ;
9387 }
@@ -97,14 +91,14 @@ public static Response FromJson(string value)
9791 }
9892 }
9993
100- if ( contents is Dictionary < string , object ? > valueDictionary )
94+ if ( contents is JsonObject valueDictionary )
10195 {
10296 // Special case code for the new session command. If the response contains
10397 // sessionId and capabilities properties, fix up the session ID and value members.
104- if ( valueDictionary . TryGetValue ( "sessionId" , out object ? session ) )
98+ if ( valueDictionary . TryGetPropertyValue ( "sessionId" , out JsonNode ? session ) )
10599 {
106- sessionId = session . ToString ( ) ;
107- if ( valueDictionary . TryGetValue ( "capabilities" , out object ? capabilities ) )
100+ sessionId = session ? . ToString ( ) ;
101+ if ( valueDictionary . TryGetPropertyValue ( "capabilities" , out JsonNode ? capabilities ) )
108102 {
109103 contents = capabilities ;
110104 }
@@ -115,7 +109,9 @@ public static Response FromJson(string value)
115109 }
116110 }
117111
118- return new Response ( sessionId , contents , WebDriverResult . Success ) ;
112+ var contentsDictionary = JsonSerializer . Deserialize ( contents , ResponseJsonSerializerContext . Default . Object ) ;
113+
114+ return new Response ( sessionId , contentsDictionary , WebDriverResult . Success ) ;
119115 }
120116
121117 /// <summary>
@@ -143,29 +139,30 @@ public static Response FromJson(string value)
143139 /// <exception cref="WebDriverException">If the JSON dictionary is not in the expected state, per spec.</exception>
144140 public static Response FromErrorJson ( string value )
145141 {
146- Dictionary < string , object ? > deserializedResponse = JsonSerializer . Deserialize < Dictionary < string , object ? > > ( value , s_jsonSerializerOptions )
147- ?? throw new WebDriverException ( "JSON error response returned \" null \" value" ) ;
142+ JsonObject responseObject = JsonNode . Parse ( value ) as JsonObject
143+ ?? throw new WebDriverException ( $ "JSON error response did not return an object { Environment . NewLine } { value } ") ;
148144
149- if ( ! deserializedResponse . TryGetValue ( "value" , out object ? valueObject ) )
145+ if ( ! responseObject . TryGetPropertyValue ( "value" , out JsonNode ? valueNode ) )
150146 {
151- throw new WebDriverException ( $ "The 'value' property was not found in the response: { Environment . NewLine } { value } ") ;
147+ throw new WebDriverException ( $ "The 'value' property was not found in the response{ Environment . NewLine } { value } ") ;
152148 }
153149
154- if ( valueObject is not Dictionary < string , object ? > valueDictionary )
150+ if ( valueNode is not JsonObject valueObject )
155151 {
156- throw new WebDriverException ( $ "The 'value' property is not a dictionary of <string, object> { Environment . NewLine } { value } ") ;
152+ throw new WebDriverException ( $ "The 'value' property is not a dictionary{ Environment . NewLine } { value } ") ;
157153 }
158154
159- if ( ! valueDictionary . TryGetValue ( "error" , out object ? errorObject ) )
155+ if ( ! valueObject . TryGetPropertyValue ( "error" , out JsonNode ? errorObject ) )
160156 {
161- throw new WebDriverException ( $ "The 'value > error' property was not found in the response: { Environment . NewLine } { value } ") ;
157+ throw new WebDriverException ( $ "The 'value > error' property was not found in the response{ Environment . NewLine } { value } ") ;
162158 }
163159
164- if ( errorObject is not string errorString )
160+ if ( errorObject is not JsonValue errorValue || ! errorValue . TryGetValue ( out string ? errorString ) )
165161 {
166162 throw new WebDriverException ( $ "The 'value > error' property is not a string{ Environment . NewLine } { value } ") ;
167163 }
168164
165+ var valueDictionary = JsonSerializer . Deserialize ( valueObject , ResponseJsonSerializerContext . Default . Object ) ;
169166 WebDriverResult status = WebDriverError . ResultFromError ( errorString ) ;
170167
171168 return new Response ( sessionId : null , valueDictionary , status ) ;
@@ -205,6 +202,7 @@ public override string ToString()
205202 }
206203 }
207204
208- [ JsonSerializable ( typeof ( Dictionary < string , object > ) ) ]
205+ [ JsonSerializable ( typeof ( object ) ) ]
206+ [ JsonSourceGenerationOptions ( Converters = [ typeof ( ResponseValueJsonConverter ) ] ) ] // we still need it to make `Object` as `Dictionary`
209207 internal sealed partial class ResponseJsonSerializerContext : JsonSerializerContext ;
210208}
0 commit comments