diff --git a/dotnet/src/webdriver/DevTools/Json/DevToolsJsonOptions.cs b/dotnet/src/webdriver/DevTools/Json/DevToolsJsonOptions.cs
new file mode 100644
index 0000000000000..4b624a9f6b43e
--- /dev/null
+++ b/dotnet/src/webdriver/DevTools/Json/DevToolsJsonOptions.cs
@@ -0,0 +1,35 @@
+//
+// Licensed to the Software Freedom Conservancy (SFC) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The SFC licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+using System.Text.Json;
+
+#nullable enable
+
+namespace OpenQA.Selenium.DevTools.Json;
+
+internal static class DevToolsJsonOptions
+{
+ public static JsonSerializerOptions Default { get; } = new JsonSerializerOptions()
+ {
+ Converters =
+ {
+ new StringConverter(),
+ }
+ };
+}
diff --git a/dotnet/src/webdriver/DevTools/Json/StringConverter.cs b/dotnet/src/webdriver/DevTools/Json/StringConverter.cs
new file mode 100644
index 0000000000000..0ba9a9627fc7f
--- /dev/null
+++ b/dotnet/src/webdriver/DevTools/Json/StringConverter.cs
@@ -0,0 +1,61 @@
+//
+// Licensed to the Software Freedom Conservancy (SFC) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The SFC licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+using System;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+#nullable enable
+
+namespace OpenQA.Selenium.DevTools.Json;
+
+internal sealed class StringConverter : JsonConverter
+{
+ public override bool HandleNull => true;
+
+ public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ try
+ {
+ return reader.GetString();
+ }
+ catch (InvalidOperationException)
+ {
+ // Fallback to read the value as bytes instead of string.
+ // System.Text.Json library throws exception when CDP remote end sends non-encoded string as binary data.
+ // Using JavaScriptEncoder.UnsafeRelaxedJsonEscaping doesn't help because the string actually is byte[].
+ // https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-Request - here "postData" property
+ // is a string, which we cannot deserialize properly. This property is marked as deprecated, and new "postDataEntries"
+ // is suggested for using, where most likely it is base64 encoded.
+
+ var bytes = reader.ValueSpan;
+ var sb = new StringBuilder(bytes.Length);
+ foreach (byte b in bytes)
+ {
+ sb.Append(Convert.ToChar(b));
+ }
+
+ return sb.ToString();
+ }
+ }
+
+ public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) =>
+ writer.WriteStringValue(value);
+}
diff --git a/dotnet/src/webdriver/cdp/README.md b/dotnet/src/webdriver/cdp/README.md
index f78d0b3d04ba4..20c23edd23a22 100644
--- a/dotnet/src/webdriver/cdp/README.md
+++ b/dotnet/src/webdriver/cdp/README.md
@@ -17,7 +17,7 @@ add an entry for version `` to the `SupportedDevToolsVersions` dictionary ini
6. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.cmd`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.cmd),
add the following block (substituting the proper value for ``):
-```
+```bash
if not exist "%1..\..\..\bazel-bin\dotnet\src\webdriver\cdp\v\DevToolsSessionDomains.cs" (
echo Generating CDP code for version
pushd "%1..\..\.."
@@ -29,7 +29,7 @@ if not exist "%1..\..\..\bazel-bin\dotnet\src\webdriver\cdp\v\DevToolsSessio
7. In [`//dotnet/src/webdriver:WebDriver.csproj.prebuild.sh`](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/src/webdriver/WebDriver.csproj.prebuild.sh),
add the following block (substituting the proper value for ``):
-```
+```bash
if [[ ! -f "$1../../../bazel-bin/dotnet/src/webdriver/cdp/v/DevToolsSessionDomains.cs" ]]
then
echo "Generating CDP code for version "
diff --git a/third_party/dotnet/devtools/src/generator/Templates/domain.hbs b/third_party/dotnet/devtools/src/generator/Templates/domain.hbs
index 1fc6271239b39..8dc01ba4fb8ea 100644
--- a/third_party/dotnet/devtools/src/generator/Templates/domain.hbs
+++ b/third_party/dotnet/devtools/src/generator/Templates/domain.hbs
@@ -61,7 +61,7 @@ namespace {{rootNamespace}}.{{domain.Name}}
if (m_eventMap.ContainsKey(e.EventName))
{
var eventData = m_eventMap[e.EventName];
- var eventArgs = e.EventData.Deserialize(eventData.EventArgsType);
+ var eventArgs = e.EventData.Deserialize(eventData.EventArgsType, global::OpenQA.Selenium.DevTools.Json.DevToolsJsonOptions.Default);
eventData.EventInvoker(eventArgs);
}
}