2009-04-30 39 views
52

ben JSON biçiminde bir sorgunun sonuçlarını döndüren bir ASP.Net web işleyicisi varKaçış Alıntı

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; 
} 

sorun bazen döndürülen veriler içinde tırnak vardır ve ihtiyacım olduğunu ifade etti javascript-kaçmak için böylece bir js nesnesine düzgün şekilde oluşturulabilir. Verilerimde alıntılar bulmanın bir yoluna ihtiyacım var (alıntılar her zaman orada değil) ve önlerine bir "/" karakteri yerleştiriyor.

yanıt örneği metin (yanlış):

{"rows":[{"id":"ABC123","length":"5""}, 
{"id":"DEF456","length":"1.35""}, 
{"id":"HIJ789","length":"36.25""}]} 

Ben "yani benim yanıtı olmalıdır kaçmak gerekir: (Ayrıca

{"rows":[{"id":"ABC123","length":"5\""}, 
{"id":"DEF456","length":"1.35\""}, 
{"id":"HIJ789","length":"36.25\""}]} 

, C# için oldukça yeni kodlama genel gerçekten) yani benim kodunda başka bir şey saçma görünüyor bana bildirin

cevap

0

Neden sadece bunu yapmayın.

string correctResponseText = wrongResponseText.Replace("\"", "\\\""); 
+0

+1 Güzel yapıldı. –

+8

Diğer özel JS karakterleri ile verileri işlemez: ters eğik çizgi, satırsonu, satır başı. –

+1

Gerçekten çok iyi yapılmadı - David'in belirttiği gibi, bu pek çok özel karakter için işe yaramayacak. @Lone Coder'ın cevabı aşağıdadır. – zcrar70

0
string.Replace(<mystring>, @"\"", @"\\""); 
+0

Çalışmıyor: 'CS1056 Beklenmeyen karakter '\' 've' CS1003 Sözdizimi hatası ',' beklenen ' – Sandro

-1

Peki, yeni başlayanlar için anahtarların etrafında tırnaklara gerek yoktur.

{rows:[,]} is valid. 

and you could dt.Table.Columns[i].ToString().Replace("\","") 

Ama çift tırnak korumak istiyorsanız, tek tırnak yapabileceğin çift tırnak Aksi

JS

yapmak aynı şekilde çalışır

String.Format("{name: \"{0}\"}",Columns[i].ToString().Replace("\","")) 
6

doğru için değişmez bir dize kaçmak için Javascript, önce tüm ters eğik çizgi karakterlerinden kaçarsınız, sonra tırnak işaretlerinden kaçarsınız (veya bunları dizge sınırlayıcılar olarak kullanırsanız kesme işaretleri).

Yani, gerekenler:

value.Replace("\\","\\\\").Replace("\"","\\\"") 

Başka ne bana atlar bir döngü içinde dize birleştirme kullanarak olmasıdır. Bu çok kötü olduğu için kötüdür. + = Işleci, varolan dizenin sonuna karakter eklemez (dizeler değişmez ve hiçbir zaman değiştirilemez), bunun yerine dizeyi ve eklenen karakterleri yeni bir dizeye kopyalar. Her seferinde daha fazla veri kopyalarken, eEvery ek satır, yöntemin yürütme süresini yaklaşık iki katına çıkarır. Dize oluşturmak için StringBuilder kullanın.

yöntemi yerine bir sütunun adını almak için ColumnName özelliğini kullanın. ToString yöntemi, ayarlanmışsa Expression özellik değerini döndürür, yalnızca bu ayarlanmadıysa ColumnName özelliğini döndürür.

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(); 
} 
+0

Kod çözme nasıl? – MonsterMMORPG

+0

@MonsterMMORPG: Kod çözemezsiniz, ayrıştırırsınız.Çözümlemenin amacı, kodun doğru şekilde ayrıştırılabilmesidir. Veri ayrıştırıldıktan sonra, dizeler özgün biçimine geri döndürülür – Guffa

34

Burada Bunun yerine JavaScriptSerializer sınıfında bakmak gerektiğini düşünüyorum ben 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(); 
} 
+3

JSON değerlendirildiğinde olabilecek olası XSS ​​saldırılarını önlemek için bu gibi bir yöntem kullanmak önemlidir: –

+1

Güzel. tek tırnakları da kodlamak –

+1

Tek tırnakların çift tırnak içinde kodlanması gerektiğini sanmıyorum –

11

bulunan etkin ve sağlam bir yöntemdir. Çok daha kararlı ve her türlü veriyi veya kaçış karakterini vb. Doğru bir şekilde kullanacaktır. Ayrıca, kodunuz çok daha temiz görünecektir.Senin durumunda

sınıf şöyle olabilir:

{"rows":[{"id":1,"name":"hello"},{"id":2,"name":"bye"}]} 

Eğlencenin:

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 }); 
} 

Bu yöntem böyle STH Örneğin ... Bir doğru tefrika json dizesi dönecektir! i html etiketine C# dize göndermek gerektiğinde :) .net 4.0 + için

140

Lone Coder tarafından açıklanan önceki batı rüzgar çözüm için HttpUtility.JavaScriptStringEncode

standart yoktur

+5

bu sadece bana yardımcı oldu;) Teşekkürler –

+0

En iyi cevap, teşekkürler –

+0

Ben tırnak içinde tırnak olduğunda sorunlara neden olan Uri.EscapeDataString kullanarak yazılım üzerinde çalışıyordum. HttpUtility.JavaScriptStringEncode'a geçmek doğru çözümdür. Karakterleri farklı şekilde gizlerler. EscapeDataString ->% 25, ​​JavaScriptStringEncode -> \\ ".... Güncelleme. Sonunda, tırnak işaretleri (") ve yüzde kabul etmek için bir api almak için hem Url.EscapeDataString (HttpUtility.JavaScriptStringEncode (str)) gerekiyordu. karakter. Daha iyi bir yol olabilir, ama umarım bu yorum birine yardımcı olur. – HockeyJ

0

İşleri oldukça güzel.

<buton onlick="alert('<<here>>')" /> 

HttpUtility.HtmlEncode