2010-02-05 14 views
6

Estoy trabajando en la escritura de algún código para borrar la entrada del usuario a mi sitio ASP.NET. Necesito borrar la entrada para eliminar todas las referencias a los caracteres ASCII 145, 146, 147, 148 que ocasionalmente reciben información de mis usuarios de Mac que están copiando y pegando el contenido que escriben en un procesador de texto en sus Macs.convirtiendo manualmente entre caracteres ASCII y .NET

Mi problema es que las tres cadenas siguientes me hacen creer que deberían dar como resultado el mismo texto.

string test1 = Convert.ToChar(147).ToString(); 
string test2 = String.Format("'{0}'", Convert.ToChar(147)); 

char[] characters = System.Text.Encoding.ASCII.GetChars(new byte[] { 147 }); 
string test3 = new string(characters); 

Sin embargo, cuando puse un cuadro de texto ASP para igualar la siguiente

txtShowValues.Text = test1 + "*" + test2 + "*" + test3; 

consigo un valor en blanco para test1, test2 funciona correctamente y salidas test3 como un '?'.

¿Alguien puede explicar lo que está sucediendo de manera diferente? Espero que esto me ayude a comprender cómo .NET está utilizando valores ASCII para caracteres de más de 128, de modo que pueda escribir un buen script de depuración.

EDIT
Los valores que mencioné (145 - 148) son comillas. Así que solo izquierda, simple derecha, doble izquierda, doble derecha.

Por "funciona correctamente" quiero decir que da como resultado una cita en mi navegador.

SEGUNDA EDICION
El siguiente código (mencionado en una respuesta) da como resultado las comillas también. Así que tal vez el problema estaba usando ASCII en la prueba 3.

char[] characters2 = System.Text.Encoding.Default.GetChars(new byte[] { 147 }); 
string test4 = new string(characters2); 

TERCERA EDICIÓN
me encontré con un mac que podía tomar prestado y fue capaz de duplicar el problema. Cuando copie y pegue texto que contenga símbolos de comillas en Word en mi aplicación web en el mac, pegará comillas (147 y 148). Cuando presiono Guardar, las cotizaciones se guardan en la base de datos, así que usaré el código con el que me ayudaste para borrar ese contenido.

FOUTH EDIT
Pasé algún tiempo escribiendo más código de ejemplo basado en las respuestas aquí y me di cuenta de que tiene algo que ver con MultiLine TextBoxes en ASP.NET. Había buena información aquí, así que decidí comenzar una nueva pregunta: ASP.NET Multiline textbox allowing input above UTF-8

+3

.NET utiliza Unicode. –

+0

, pero ¿por qué funciona test2? En todo caso, esperaba que test3 funcionara. –

+0

¿Qué quiere decir con "funciona correctamente"? Es un personaje de control invisible: se supone que se muestra como una cadena en blanco. ¿Qué salida esperas? –

Respuesta

10

El carácter 147 es U + 0093 SET TRANSMIT STATE. Al igual que todos los caracteres Unicode en el rango 0-255, es el mismo que el carácter ISO-8859-1 del mismo número. ISO-8859-1 asigna 147 a este código de control invisible.

Lo que está pensando no es 'ASCII' o incluso 'ISO-8859-1', pero la página de códigos de Windows 1252. Esta es una codificación no estándar que es como 8859-1, pero asigna los caracteres 128-159 a varias extensiones tipográficas, como citas inteligentes en lugar de los códigos de control en gran parte inútiles. En la página de códigos 1252, el carácter 147 es , también conocido como U + 201C IZQUIERDA DOBLE CITA DE MARCA.

Si desea convertir las páginas de códigos de Windows (a menudo conocido erróneamente como 'ANSI') a los caracteres Unicode que tendrá que especificar la página de códigos que desee, por ejemplo:

System.Text.Encoding.getEncoding(1252).GetChars(new byte[] { 147 }) 

System.Text.Encoding.Default te dará la codificación por defecto en su servidor. Para un servidor en la configuración regional de Europa occidental, será 1252. En otro lugar, no lo será. En general, no es una buena idea tener una dependencia en la página de códigos predeterminada de la configuración regional en una aplicación de servidor.

En cualquier caso, debería no obtener bytes como 147 representando un en la entrada de una aplicación web. Eso solo ocurrirá si su página está codificada en la página de códigos 1252 (y solo para confundir y confundir aún más, cuando dice que su página está en formato ISO-8859-1, los navegadores usarán silenciosamente la página de códigos 1252). Su página también puede estar en 1252 si no ha especificado ninguna codificación (el navegador adivina, otras configuraciones locales adivinarán páginas de códigos diferentes, por lo que todo será un gran desastre).

Asegúrese de utilizar UTF-8 para todas las codificaciones en su aplicación web, y mark your pages as such. Hoy, todas las aplicaciones web deberían usar UTF-8.

+0

@bobince - Gran información, muchas gracias.Supongo que no tendrías ningún enlace a la documentación sobre este tipo de cosas. Solo trato de aprender todo lo posible sobre este tema antes de poner una solución en su lugar. –

+0

¡El artículo de Spolsky por lo general sale volando en este punto! (http://www.joelonsoftware.com/articles/Unicode.html) ... Tengo mis reservas sobre algunos de los materiales en esto, pero supongo que es un manual bastante razonable. – bobince

+0

@bobince - ¿Hay alguna posibilidad de que un usuario copie y pegue desde un procesador de textos para enviar los valores a la interfaz web? Este es un problema bastante raro, pero cada usuario que he entrevistado dijo que estaba copiando y pegando desde su procesador de textos en su mac. –

0

Recibo signos de interrogación para los 3 de ellos en una aplicación de consola (.NET 3.5SP1). Todos deberían ser equivalentes, hasta donde yo sé. John Knoeller tiene razón con respecto a ASCII frente a ANSI.

¿Ha intentado utilizar uno de los GetBytes() de las clases de codificación en la cadena original e iterar, eliminando (copiando bytes "buenos" a otro buffer) los valores que no desea?

p. Ej. (usando Linq):

byte[] original = System.Text.Encoding.ASCII.GetBytes(badString); 
byte[] clean = (from b in original where b < 145 || b > 148 select b).ToArray<byte>(); 
string cleanString = System.Text.Encoding.ASCII.GetString(clean); 

ASCII es probablemente el incorrecto para usar aquí, para ser honesto; si el texto original es Unicode, es concebible que haga cosas malas (si se pasa el UTF-16, por ejemplo).

3

.NET utiliza Unicode (UCS-2) que es el mismo que ASCII sólo para valores por debajo de 128.

ASCII no define los valores por encima de 127.

Creo que puede estar pensando en ANSI, que define los valores por encima de 127 como (la mayoría) de los caracteres de idioma necesarios para la mayoría de los idiomas europeos. o OEM (el juego de caracteres original de IBM pc) que define caracteres> 127 como (principalmente) símbolos.

La diferencia en la interpretación de los caracteres superiores a 127 se denomina página de códigos o codificación. (de ahí System.Text.Encoding). Por lo tanto, probablemente podría hacer funcionar la prueba 3 si utilizó una codificación diferente, quizás System.Text.Encoding.Default.

Editar: Ok, ahora que sabemos que la codificación que desea es ANSI, está más claro lo que está sucediendo.

La regla para las conversiones de caracteres es reemplazar los caracteres que no se pueden representar en la codificación como algún otro carácter, generalmente un cuadro. Pero para ASCII, no hay un carácter de cuadro, ¿entonces usa un? en lugar. Esto explica la prueba 3.

test1 y 2 utilizan Convert.ToChar con una constante entera. Que interpretará la entrada como un carácter UNICODE, no un carácter ANSI, por lo que no se aplica ninguna conversión. El carácter Unicode 147 es un carácter no imprimible.

Cuestiones relacionadas