quot - para que sirven las secuencias de escape en c#
Escape Quote in C#para el consumo de JavaScript (8)
Tengo un controlador web ASP.Net que devuelve resultados de una consulta en formato JSON
public static String dt2JSON(DataTable dt)
{
String s = "{/"rows/":[";
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
s += "{";
for (int i = 0; i < dr.Table.Columns.Count; i++)
{
s += "/"" + dr.Table.Columns[i].ToString() + "/":/"" + dr[i].ToString() + "/",";
}
s = s.Remove(s.Length - 1, 1);
s += "},";
}
s = s.Remove(s.Length - 1, 1);
}
s += "]}";
return s;
}
El problema es que a veces los datos devueltos tienen comillas y necesito javascript-escapar de estos para que puedan crearse correctamente en un objeto js. Necesito una forma de encontrar citas en mis datos (las citas no están disponibles todas las veces) y colocar un carácter "/" delante de ellos.
Ejemplo de texto de respuesta (incorrecto):
{"rows":[{"id":"ABC123","length":"5""},
{"id":"DEF456","length":"1.35""},
{"id":"HIJ789","length":"36.25""}]}
Necesitaría escapar del "entonces mi respuesta debería ser:
{"rows":[{"id":"ABC123","length":"5/""},
{"id":"DEF456","length":"1.35/""},
{"id":"HIJ789","length":"36.25/""}]}
Además, soy bastante nuevo en C # (en general, la codificación en general) así que si algo más en mi código parece tonto, házmelo saber.
¿Por qué no haces esto?
string correctResponseText = wrongResponseText.Replace("/"", "///"");
Aquí hay un método eficiente y robusto que encontré en http://www.west-wind.com/weblog/posts/114530.aspx
/// <summary>
/// Encodes a string to be represented as a string literal. The format
/// is essentially a JSON string.
///
/// The string returned includes outer quotes
/// Example Output: "Hello /"Rick/"!/r/nRock on"
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string EncodeJsString(string s)
{
StringBuilder sb = new StringBuilder();
sb.Append("/"");
foreach (char c in s)
{
switch (c)
{
case ''/"'':
sb.Append("///"");
break;
case ''//':
sb.Append("////");
break;
case ''/b'':
sb.Append("//b");
break;
case ''/f'':
sb.Append("//f");
break;
case ''/n'':
sb.Append("//n");
break;
case ''/r'':
sb.Append("//r");
break;
case ''/t'':
sb.Append("//t");
break;
default:
int i = (int)c;
if (i < 32 || i > 127)
{
sb.AppendFormat("//u{0:X04}", i);
}
else
{
sb.Append(c);
}
break;
}
}
sb.Append("/"");
return sb.ToString();
}
Bueno, para empezar, no necesitas cotizaciones para las llaves.
{rows:[,]} is valid.
and you could dt.Table.Columns[i].ToString().Replace("/","")
Pero si desea conservar las comillas dobles, las comillas simples funcionan de la misma manera que las comillas dobles en JS
De lo contrario, podrías hacer
String.Format("{name: /"{0}/"}",Columns[i].ToString().Replace("/",""))
Creo que deberías mirar la clase JavaScriptSerializer. Es mucho más estable y manejará correctamente cualquier tipo de datos o caracteres de escape, etc. Además, su código se verá mucho más limpio.
En tu caso, tu clase puede verse así:
public static String dt2JSON(DataTable dt) {
var rows = new List<Object>();
foreach(DataRow row in dt.Rows)
{
var rowData = new Dictionary<string, object>();
foreach(DataColumn col in dt.Columns)
rowData[col.ColumnName] = row[col];
rows.Add(rowData);
}
var js = new JavaScriptSerializer();
return js.Serialize(new { rows = rows });
}
Este método devolverá una cadena json serializada correctamente ... Por ejemplo, algo como esto:
{"rows":[{"id":1,"name":"hello"},{"id":2,"name":"bye"}]}
¡Que te diviertas! :)
Funciona cuando necesito enviar cadenas desde la etiqueta C # a html.
<buton onlick="alert(''<< here >>'')" />
HttpUtility.HtmlEncode
Para .net 4.0 + existe el estándar HttpUtility.JavaScriptStringEncode
Para la solución de viento oeste anterior descrita por Lone Coder es bastante agradable
Para escapar correctamente de un literal de cadena para Javascript, primero escapa de todos los caracteres de barra invertida, luego se escapa de las comillas (o apóstrofes si los usa como delimitadores de cadena).
Entonces, lo que necesitas es:
value.Replace("//","////").Replace("/"","///"")
Lo que más salta a la vista es que está utilizando la concatenación de cadenas en un bucle. Esto es malo, ya que se escala muy pobremente. El operador + = no agrega caracteres al final de la cadena existente (ya que las cadenas son inmutables y nunca se pueden cambiar), en su lugar copia la cadena y los caracteres agregados a una nueva cadena. A medida que copie más y más datos cada vez, cada fila adicional duplica aproximadamente el tiempo de ejecución del método. Use un StringBuilder para construir la cadena en su lugar.
Use la propiedad ColumnName
para obtener el nombre de una columna en lugar del método ToString
. El método ToString
devuelve el valor de la propiedad Expression
si está configurado, solo si no se establece devuelve la propiedad ColumnName
.
public static String dt2JSON(DataTable dt) {
StringBuilder s = new StringBuilder("{/"rows/":[");
bool firstLine = true;
foreach (DataRow dr in dt.Rows) {
if (firstLine) {
firstLine = false;
} else {
s.Append('','');
}
s.Append(''{'');
for (int i = 0; i < dr.Table.Columns.Count; i++) {
if (i > 0) {
s.Append('','');
}
string name = dt.Columns[i].ColumnName;
string value = dr[i].ToString();
s.Append(''"'')
.Append(name.Replace("//","////").Replace("/"","///""))
.Append("/":/"")
.Append(value.Replace("//","////").Replace("/"","///""))
.Append(''"'');
}
s.Append("}");
}
s.Append("]}");
return s.ToString();
}
string.Replace(<mystring>, @"/"", @"//"");