2424using System . Text . Json ;
2525using System . Text . Json . Serialization ;
2626
27+ #nullable enable
28+
2729namespace OpenQA . Selenium
2830{
2931 /// <summary>
@@ -48,88 +50,98 @@ public Response()
4850 /// Initializes a new instance of the <see cref="Response"/> class
4951 /// </summary>
5052 /// <param name="sessionId">Session ID in use</param>
51- public Response ( SessionId sessionId )
53+ public Response ( SessionId ? sessionId )
5254 {
53- if ( sessionId != null )
54- {
55- this . SessionId = sessionId . ToString ( ) ;
56- }
55+ this . SessionId = sessionId ? . ToString ( ) ;
56+ }
57+
58+ /// <summary>
59+ /// Initializes a new instance of the <see cref="Response"/> class
60+ /// </summary>
61+ /// <param name="sessionId">The Session ID in use, if any.</param>
62+ /// <param name="value">The JSON payload of the response.</param>
63+ /// <param name="status">The WebDriver result status of the response.</param>
64+ public Response ( string ? sessionId , object ? value , WebDriverResult status )
65+ {
66+ this . SessionId = sessionId ;
67+ this . Value = value ;
68+ this . Status = status ;
5769 }
5870
5971 /// <summary>
6072 /// Returns a new <see cref="Response"/> from a JSON-encoded string.
6173 /// </summary>
6274 /// <param name="value">The JSON string to deserialize into a <see cref="Response"/>.</param>
6375 /// <returns>A <see cref="Response"/> object described by the JSON string.</returns>
76+ /// <exception cref="ArgumentNullException">If <paramref name="value"/> is <see langword="null"/>.</exception>
77+ /// <exception cref="JsonException">If <paramref name="value"/> is not a valid JSON object.</exception>
6478 public static Response FromJson ( string value )
6579 {
66- Dictionary < string , object > rawResponse = JsonSerializer . Deserialize < Dictionary < string , object > > ( value , s_jsonSerializerOptions )
80+ Dictionary < string , object ? > rawResponse = JsonSerializer . Deserialize < Dictionary < string , object ? > > ( value , s_jsonSerializerOptions )
6781 ?? throw new WebDriverException ( "JSON success response returned \" null\" value" ) ;
6882
69- var response = new Response ( ) ;
83+ object ? contents ;
84+ string ? sessionId = null ;
7085
71- if ( rawResponse . ContainsKey ( "sessionId" ) )
86+ if ( rawResponse . TryGetValue ( "sessionId" , out object ? s ) && s is not null )
7287 {
73- if ( rawResponse [ "sessionId" ] != null )
74- {
75- response . SessionId = rawResponse [ "sessionId" ] . ToString ( ) ;
76- }
88+ sessionId = s . ToString ( ) ;
7789 }
7890
79- if ( rawResponse . TryGetValue ( "value" , out object valueObj ) )
91+ if ( rawResponse . TryGetValue ( "value" , out object ? valueObj ) )
8092 {
81- response . Value = valueObj ;
93+ contents = valueObj ;
8294 }
83-
84- // If the returned object does *not* have a "value" property
85- // the response value should be the entirety of the response.
86- // TODO: Remove this if statement altogether; there should
87- // never be a spec-compliant response that does not contain a
88- // value property.
89- if ( ! rawResponse . ContainsKey ( "value" ) && response . Value == null )
95+ else
9096 {
97+ // If the returned object does *not* have a "value" property
98+ // the response value should be the entirety of the response.
99+ // TODO: Remove this if statement altogether; there should
100+ // never be a spec-compliant response that does not contain a
101+ // value property.
102+
91103 // Special-case for the new session command, where the "capabilities"
92104 // property of the response is the actual value we're interested in.
93- if ( rawResponse . ContainsKey ( "capabilities" ) )
105+ if ( rawResponse . TryGetValue ( "capabilities" , out object ? capabilities ) )
94106 {
95- response . Value = rawResponse [ " capabilities" ] ;
107+ contents = capabilities ;
96108 }
97109 else
98110 {
99- response . Value = rawResponse ;
111+ contents = rawResponse ;
100112 }
101113 }
102114
103- if ( response . Value is Dictionary < string , object > valueDictionary )
115+ if ( contents is Dictionary < string , object ? > valueDictionary )
104116 {
105117 // Special case code for the new session command. If the response contains
106118 // sessionId and capabilities properties, fix up the session ID and value members.
107- if ( valueDictionary . ContainsKey ( "sessionId" ) )
119+ if ( valueDictionary . TryGetValue ( "sessionId" , out object ? session ) )
108120 {
109- response . SessionId = valueDictionary [ "sessionId" ] . ToString ( ) ;
110- if ( valueDictionary . TryGetValue ( "capabilities" , out object capabilities ) )
121+ sessionId = session . ToString ( ) ;
122+ if ( valueDictionary . TryGetValue ( "capabilities" , out object ? capabilities ) )
111123 {
112- response . Value = capabilities ;
124+ contents = capabilities ;
113125 }
114126 else
115127 {
116- response . Value = valueDictionary [ "value" ] ;
128+ contents = valueDictionary [ "value" ] ;
117129 }
118130 }
119131 }
120132
121- return response ;
133+ return new Response ( sessionId , contents , WebDriverResult . Success ) ;
122134 }
123135
124136 /// <summary>
125137 /// Gets or sets the value from JSON.
126138 /// </summary>
127- public object Value { get ; set ; }
139+ public object ? Value { get ; set ; }
128140
129141 /// <summary>
130142 /// Gets or sets the session ID.
131143 /// </summary>
132- public string SessionId { get ; set ; }
144+ public string ? SessionId { get ; set ; }
133145
134146 /// <summary>
135147 /// Gets or sets the status value of the response.
@@ -142,26 +154,25 @@ public static Response FromJson(string value)
142154 /// </summary>
143155 /// <param name="value">The JSON string to deserialize into a <see cref="Response"/>.</param>
144156 /// <returns>A <see cref="Response"/> object described by the JSON string.</returns>
157+ /// <exception cref="ArgumentNullException">If <paramref name="value"/> is <see langword="null"/>.</exception>
158+ /// <exception cref="JsonException">If <paramref name="value"/> is not a valid JSON object.</exception>
159+ /// <exception cref="WebDriverException">If the JSON dictionary is not in the expected state, per spec.</exception>
145160 public static Response FromErrorJson ( string value )
146161 {
147- var deserializedResponse = JsonSerializer . Deserialize < Dictionary < string , object > > ( value , s_jsonSerializerOptions )
162+ Dictionary < string , object ? > deserializedResponse = JsonSerializer . Deserialize < Dictionary < string , object ? > > ( value , s_jsonSerializerOptions )
148163 ?? throw new WebDriverException ( "JSON error response returned \" null\" value" ) ;
149164
150- var response = new Response ( ) ;
151-
152- if ( ! deserializedResponse . TryGetValue ( "value" , out var valueObject ) )
165+ if ( ! deserializedResponse . TryGetValue ( "value" , out object ? valueObject ) )
153166 {
154167 throw new WebDriverException ( $ "The 'value' property was not found in the response:{ Environment . NewLine } { value } ") ;
155168 }
156169
157- if ( valueObject is not Dictionary < string , object > valueDictionary )
170+ if ( valueObject is not Dictionary < string , object ? > valueDictionary )
158171 {
159172 throw new WebDriverException ( $ "The 'value' property is not a dictionary of <string, object>{ Environment . NewLine } { value } ") ;
160173 }
161174
162- response . Value = valueDictionary ;
163-
164- if ( ! valueDictionary . TryGetValue ( "error" , out var errorObject ) )
175+ if ( ! valueDictionary . TryGetValue ( "error" , out object ? errorObject ) )
165176 {
166177 throw new WebDriverException ( $ "The 'value > error' property was not found in the response:{ Environment . NewLine } { value } ") ;
167178 }
@@ -171,11 +182,9 @@ public static Response FromErrorJson(string value)
171182 throw new WebDriverException ( $ "The 'value > error' property is not a string{ Environment . NewLine } { value } ") ;
172183 }
173184
174- response . Value = deserializedResponse [ "value" ] ;
175-
176- response . Status = WebDriverError . ResultFromError ( errorString ) ;
185+ WebDriverResult status = WebDriverError . ResultFromError ( errorString ) ;
177186
178- return response ;
187+ return new Response ( sessionId : null , valueDictionary , status ) ;
179188 }
180189
181190 /// <summary>
0 commit comments