¿Configurar el deserializador .NET WCF UTF-8 para modificar / descartar caracteres de forma no más corta en lugar de lanzar una excepción?

Tenemos un servicio web SOAP alojado a través de WCF.

Uno de los clientes de los que recibimos datos de vez en cuando codifica UTF-8 usando la forma no más corta (Verhttp://www.unicode.org/versions/corrigendum1.html para un poco de información sobre esto).

No es fácil modificar el cliente porque nuestro código no codifica estos caracteres de forma no más corta.

En cambio, nos gustaría editar el servicio WCF para descartar estos caracteres, reemplazarlos con otros caracteres de marcador de posición o incluso aceptar los caracteres de forma no más corta. Cualquiera de estos sería aceptable para nuestro caso de uso, aunque las opciones anteriores serían preferidas ya que disminuyen cualquier riesgo de seguridad.

Mirando el rastro de la pila:

System.ServiceModel.Dispatcher.NetDispatcherFaultException: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://www.mydomain.com/:mytype. The InnerException message was 'There was an error deserializing the object of type MyNamespace.MyType`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c461934e089]]. '????' contains invalid UTF8 bytes.'.  Please see InnerException for more details. ---> System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type MyNamespace.MyType`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c461934e089]]. '????' contains invalid UTF8 bytes. ---> System.Xml.XmlException: '????' contains invalid UTF8 bytes. ---> System.Text.DecoderFallbackException: Unable to translate bytes [C0] at index 0 from specified code page to Unicode.
   at System.Text.DecoderExceptionFallbackBuffer.Throw(Byte[] bytesUnknown, Int32 index)
   at System.Text.DecoderExceptionFallbackBuffer.Fallback(Byte[] bytesUnknown, Int32 index)
   at System.Text.DecoderFallbackBuffer.InternalFallback(Byte[] bytes, Byte* pBytes, Char*& chars)
   at System.Text.UTF8Encoding.FallbackInvalidByteSequence(Byte*& pSrc, Int32 ch, DecoderFallbackBuffer fallback, Char*& pTarget)
   at System.Text.UTF8Encoding.GetChars(Byte* bytes, Int32 byteCount, Char* chars, Int32 charCount, DecoderNLS baseDecoder)
   at System.Text.UTF8Encoding.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, Char[] chars, Int32 charIndex)
   at System.Xml.XmlConverter.ToChars(Byte[] buffer, Int32 offset, Int32 count, Char[] chars, Int32 charOffset)
   --- End of inner exception stack trace ---
   at System.Xml.XmlConverter.ToChars(Byte[] buffer, Int32 offset, Int32 count, Char[] chars, Int32 charOffset)
   at System.Xml.XmlBufferReader.GetChars(Int32 offset, Int32 length, Char[] chars)
   at System.Xml.ValueHandle.GetCharsText()
   at System.Xml.ValueHandle.GetString()
   at System.Xml.XmlBaseReader.get_Value()
   at System.Xml.XmlDictionaryReader.ReadContentAsString(Int32 maxStringContentLength)
   at System.Xml.XmlBaseReader.ReadContentAsString()
   at System.Xml.XmlBaseReader.ReadElementContentAsString()
   at System.Runtime.Serialization.XmlReaderDelegator.ReadElementContentAsString()
   at ReadOrbliteCompatibleArrayOfstringFromXml(XmlReaderDelegator , XmlObjectSerializerReadContext , XmlDictionaryString , XmlDictionaryString , CollectionDataContract )
   at System.Runtime.Serialization.CollectionDataContract.ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator reader, String name, String ns, DataContract& dataContract)
   at System.Runtime.Serialization.XmlObjectSerializerReadContext.InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, String name, String ns)
   at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName)
   --- End of inner exception stack trace ---
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, Boolean isRequest)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, Object[] parameters, Boolean isRequest)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader reader, MessageVersion version, String action, MessageDescription messageDescription, Object[] parameters, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(Message message, Object[] parameters, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

Parece que lo que queremos es cambiar el retroceso del decodificador deSystem.Text.DecoderExceptionFallback aSystem.Text.DecoderReplacementFallback.

¿Alguien puede señalarme el lugar y la forma correctos para anular la reserva de excepción predeterminada con una reserva de reemplazo?

Respuestas a la pregunta(1)

Su respuesta a la pregunta