I had a situation today where an xml document had a directive indicating it was utf-8.  So, the code in question was reading in the “string” of that xml then attempting to de-serialize it using an Xsd generated type.
What you end up with is an exception indicating that there’s an error in the Xml document at (1,1) or something to that effect.
The fix is, run it through a memory stream – which reads the string, but at utf8 bytes – if you have things that fall outside of 8 bit chars, you’ll get an exception.

01//Need to read it to bytes, to undo the fact that strings are UTF-16 all the time.
02//We want it to handle it as UTF8.
03byte[] bytes = Encoding.UTF8.GetBytes(_myXmlString);
04
05TargetType myInstance = null;
06using (MemoryStream memStream = new MemoryStream(bytes))
07{
08    XmlSerializer tokenSerializer = new XmlSerializer(typeof(TargetType));
09    myInstance = (TargetType)tokenSerializer.Deserialize(memStream);
10}

Writing is similar – also, adding the default namespace prevents the additional xmlns additions that aren’t necessary:

01XmlWriterSettings settings = new XmlWriterSettings()
02{
03    Encoding = Encoding.UTF8,
04    Indent = true,
05    NewLineOnAttributes = true,
06};
07
08XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
09xmlnsEmpty.Add("""http://www.wow.thisworks.com/2010/05");
10
11MemoryStream memStr = new MemoryStream();
12using (XmlWriter writer = XmlTextWriter.Create(memStr, settings))
13{
14    XmlSerializer tokenSerializer = new XmlSerializer(typeof(TargetType));
15    tokenSerializer.Serialize(writer, theInstance, xmlnsEmpty);
16}