JSON स्ट्रिंग से कैसे बचें?


97

क्या कोई वर्ग / कार्य उपलब्ध है जो आसान JSON से बचने के लिए उपयोग किया जा सकता है? मैं नहीं बल्कि अपना खुद का लिखना होगा।


3
JsonConvert.ToString () ने मेरे लिए काम किया।
मार्टिन लॉट्टरिंग

जवाबों:


74

मैं उपयोग करता हूं System.Web.HttpUtility.JavaScriptStringEncode

string quoted = HttpUtility.JavaScriptStringEncode(input);

5
मैंने इसका उपयोग System.Web.Helpers.Json.EncodeVS2015 में लापता होने से बचने के लिए किया , लेकिन इसके (input, true)लिए वास्तविक उद्धरणों को भी शामिल करने के लिए पैरामीटर की आवश्यकता है ।
लैपो

47

Newtonsoft से बहुत लोकप्रिय Json.Net परियोजना का उपयोग करने वालों के लिए यह कार्य तुच्छ है:

using Newtonsoft.Json;

....
var s = JsonConvert.ToString(@"a\b");
Console.WriteLine(s);
....

यह कोड प्रिंट करता है:

"एक \\ ख"

यही है, जिसके परिणामस्वरूप स्ट्रिंग मान में उद्धरण के साथ-साथ बच गए बैकस्लैश भी शामिल हैं।


2
मैं एन्कोडेड और अनचाहे मार्ग से बचने के लिए इस विधि को पुन: पेश नहीं कर सकता। मेरे पथ "WatchedPath": "\\\\myserver\\output"हो जाता है "\"\\\\\\\\myserver\\\\output\""जो बहुत अस्वीकार्य है।
slestak

3
ऊपर की विधि deserializing के लिए नहीं है - रैटर इसका उपयोग तब किया जाता है जब आप मैन्युअल रूप से JSON टेक्स्ट बनाना चाहते हैं और आपके पास C # स्ट्रिंग है और पाठ के रूप में इसका उचित प्रतिनिधित्व प्राप्त करने की आवश्यकता है।
Dror Harari

@slestak, मुझे लगता है कि मैं उसी मुद्दे का सामना कर रहा हूं जो आप यहां थे। क्या आपको एक समाधान मिला?
जीपी 24

@ GP24 IIRC, मैंने नहीं किया। क्षमा करें, मेरे पास और कोई जानकारी नहीं है।
slestak

कोई बात नहीं, जवाब देने के लिए धन्यवाद। मैंने यह किया है अगर यह आपकी मदद करता है: yourAnnoyingDoubleEncodedString.Replace ("\\\\", "\\")। प्रतिस्थापित करें ("\\\" "," \ "");
GP24

38

देजन द्वारा दिए गए उत्तर पर , आप क्या कर सकते हैं । .NET फ्रेमवर्क असेंबली आयातSystem.Web.Helpers करें, फिर निम्न फ़ंक्शन का उपयोग करें:

static string EscapeForJson(string s) {
  string quoted = System.Web.Helpers.Json.Encode(s);
  return quoted.Substring(1, quoted.Length - 2);
}

Substringकॉल की आवश्यकता है, के बाद से Encodeस्वचालित रूप से दोहरे उद्धरण चिह्नों के साथ तार चारों ओर से घेरे।


System.Web.Helpers जैसा दिखता है ।net 4.0
सर्ज

... और विजुअल स्टूडियो 2015 में भी नहीं।
लैपो

5
यह ASP.NET वेब पेज 2.0 का हिस्सा है। इसे NuGet का उपयोग करके जोड़ा जा सकता है। यह ढांचे का हिस्सा नहीं है।
मुवन

30

हां, बस अपने यूटिल्स वर्ग या कुछ के लिए निम्नलिखित फ़ंक्शन जोड़ें:

    public static string cleanForJSON(string s)
    {
        if (s == null || s.Length == 0) {
            return "";
        }

        char         c = '\0';
        int          i;
        int          len = s.Length;
        StringBuilder sb = new StringBuilder(len + 4);
        String       t;

        for (i = 0; i < len; i += 1) {
            c = s[i];
            switch (c) {
                case '\\':
                case '"':
                    sb.Append('\\');
                    sb.Append(c);
                    break;
                case '/':
                    sb.Append('\\');
                    sb.Append(c);
                    break;
                case '\b':
                    sb.Append("\\b");
                    break;
                case '\t':
                    sb.Append("\\t");
                    break;
                case '\n':
                    sb.Append("\\n");
                    break;
                case '\f':
                    sb.Append("\\f");
                    break;
                case '\r':
                    sb.Append("\\r");
                    break;
                default:
                    if (c < ' ') {
                        t = "000" + String.Format("X", c);
                        sb.Append("\\u" + t.Substring(t.Length - 4));
                    } else {
                        sb.Append(c);
                    }
                    break;
            }
        }
        return sb.ToString();
    }

3
आपको भागने की आवश्यकता क्यों है /?
drzaus

मुझे पता है कि यह एक पुराना उत्तर है और मुझे यह देखकर खुशी हुई कि यह मुझे किसी बाहरी पुस्तकालय पर भरोसा नहीं करना था, लेकिन मैंने देखा कि एक नियंत्रण चरित्र के लिए डिफ़ॉल्ट मामला हमेशा "\\ u000X" वापस आ जाएगा। मेरा मानना ​​है कि आपको पहले एक इंट में चार कास्ट करने की आवश्यकता है। इसे बदलने के बारे में विचार करेंstring t = "000" + ((int)c).ToString("X");
Jan Discart

सही डिफ़ॉल्ट मामला होना चाहिए:t = "000" + String.Format("{0:X}",(int) c);
daniatic

16

मैंने json के लिए स्ट्रिंग मान से बचने के लिए निम्नलिखित कोड का उपयोग किया है। आपको निम्नलिखित कोड के आउटपुट में अपना "" जोड़ना होगा:

public static string EscapeStringValue(string value)
{
    const char BACK_SLASH = '\\';
    const char SLASH = '/';
    const char DBL_QUOTE = '"';

    var output = new StringBuilder(value.Length);
    foreach (char c in value)
    {
        switch (c)
        {
            case SLASH:
                output.AppendFormat("{0}{1}", BACK_SLASH, SLASH);
                break;

            case BACK_SLASH:
                output.AppendFormat("{0}{0}", BACK_SLASH);
                break;

            case DBL_QUOTE:
                output.AppendFormat("{0}{1}",BACK_SLASH,DBL_QUOTE);
                break;

            default:
                output.Append(c);
                break;
        }
    }

    return output.ToString();
}

1
इससे वास्तव में मेरा दिन बच गया। आपका बहुत बहुत धन्यवाद!
कासौट

8
उत्पादन में इस कोड का उपयोग न करें! भागने वाला यह JSON महत्वपूर्ण विशेष पात्रों को याद करता है। देखें: stackoverflow.com/a/33799784
vog

2
यह कोड सभी विशेष मामलों को कवर नहीं करता है। उत्पादन में उपयोग न करें।
Envil

2
पहिए को फिर से
लगायें

6

यहां दी गई विधियां दोषपूर्ण हैं।
जब आप अभी-अभी System.Web.HttpUtility.JavaScriptEncode का उपयोग कर सकते हैं तो उद्यम क्यों करें?

यदि आप कम रूपरेखा पर हैं, तो आप इसे मोनो से पेस्ट कॉपी कर सकते हैं

मोनो-प्रोजेक्ट के सौजन्य से @ https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs

    public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
    {
        if (string.IsNullOrEmpty(value))
            return addDoubleQuotes ? "\"\"" : string.Empty;

        int len = value.Length;
        bool needEncode = false;
        char c;
        for (int i = 0; i < len; i++)
        {
            c = value[i];

            if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
            {
                needEncode = true;
                break;
            }
        }

        if (!needEncode)
            return addDoubleQuotes ? "\"" + value + "\"" : value;

        var sb = new System.Text.StringBuilder();
        if (addDoubleQuotes)
            sb.Append('"');

        for (int i = 0; i < len; i++)
        {
            c = value[i];
            if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
                sb.AppendFormat("\\u{0:x4}", (int)c);
            else switch ((int)c)
                {
                    case 8:
                        sb.Append("\\b");
                        break;

                    case 9:
                        sb.Append("\\t");
                        break;

                    case 10:
                        sb.Append("\\n");
                        break;

                    case 12:
                        sb.Append("\\f");
                        break;

                    case 13:
                        sb.Append("\\r");
                        break;

                    case 34:
                        sb.Append("\\\"");
                        break;

                    case 92:
                        sb.Append("\\\\");
                        break;

                    default:
                        sb.Append(c);
                        break;
                }
        }

        if (addDoubleQuotes)
            sb.Append('"');

        return sb.ToString();
    }

इसमें कॉम्पैक्ट किया जा सकता है

// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
{

    private static  bool NeedEscape(string src, int i)
    {
        char c = src[i];
        return c < 32 || c == '"' || c == '\\'
            // Broken lead surrogate
            || (c >= '\uD800' && c <= '\uDBFF' &&
                (i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
            // Broken tail surrogate
            || (c >= '\uDC00' && c <= '\uDFFF' &&
                (i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
            // To produce valid JavaScript
            || c == '\u2028' || c == '\u2029'
            // Escape "</" for <script> tags
            || (c == '/' && i > 0 && src[i - 1] == '<');
    }



    public static string EscapeString(string src)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        int start = 0;
        for (int i = 0; i < src.Length; i++)
            if (NeedEscape(src, i))
            {
                sb.Append(src, start, i - start);
                switch (src[i])
                {
                    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;
                    case '\"': sb.Append("\\\""); break;
                    case '\\': sb.Append("\\\\"); break;
                    case '/': sb.Append("\\/"); break;
                    default:
                        sb.Append("\\u");
                        sb.Append(((int)src[i]).ToString("x04"));
                        break;
                }
                start = i + 1;
            }
        sb.Append(src, start, src.Length - start);
        return sb.ToString();
    }
}

4

मैं उल्लेख किए गए JSON.NET पुस्तकालय का उपयोग करने की भी सिफारिश करूंगा , लेकिन यदि आपको परिणामी JSON स्ट्रिंग में यूनिकोड वर्ण (जैसे \ uXXXX प्रारूप) से बचना है, तो आपको इसे स्वयं करना पड़ सकता है। एक उदाहरण के लिए यूनिकोड स्ट्रिंग्स से बच निकली एस्की स्ट्रिंग पर एक नज़र डालें ।


4

मैंने इनमें से कुछ जवाबों पर एक लंबी स्ट्रिंग और एक छोटी स्ट्रिंग के लिए गति परीक्षण चलाया। क्लाइव पैटर्सन का कोड एक अच्छा सा जीता, संभवत: इसलिए क्योंकि दूसरों को सीरियलाइजेशन विकल्पों में शामिल किया जा रहा है। यहाँ मेरे परिणाम हैं:

Apple Banana
System.Web.HttpUtility.JavaScriptStringEncode: 140ms
System.Web.Helpers.Json.Encode: 326ms
Newtonsoft.Json.JsonConvert.ToString: 230ms
Clive Paterson: 108ms

\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\"things\to\escape\some\long\path\with\lots"\of\things\to\escape
System.Web.HttpUtility.JavaScriptStringEncode: 2849ms
System.Web.Helpers.Json.Encode: 3300ms
Newtonsoft.Json.JsonConvert.ToString: 2827ms
Clive Paterson: 1173ms

और यहाँ परीक्षण कोड है:

public static void Main(string[] args)
{
    var testStr1 = "Apple Banana";
    var testStr2 = @"\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\""things\to\escape\some\long\path\with\lots""\of\things\to\escape";

    foreach (var testStr in new[] { testStr1, testStr2 })
    {
        var results = new Dictionary<string,List<long>>();

        for (var n = 0; n < 10; n++)
        {
            var count = 1000 * 1000;

            var sw = Stopwatch.StartNew();
            for (var i = 0; i < count; i++)
            {
                var s = System.Web.HttpUtility.JavaScriptStringEncode(testStr);
            }
            var t = sw.ElapsedMilliseconds;
            results.GetOrCreate("System.Web.HttpUtility.JavaScriptStringEncode").Add(t);

            sw = Stopwatch.StartNew();
            for (var i = 0; i < count; i++)
            {
                var s = System.Web.Helpers.Json.Encode(testStr);
            }
            t = sw.ElapsedMilliseconds;
            results.GetOrCreate("System.Web.Helpers.Json.Encode").Add(t);

            sw = Stopwatch.StartNew();
            for (var i = 0; i < count; i++)
            {
                var s = Newtonsoft.Json.JsonConvert.ToString(testStr);
            }
            t = sw.ElapsedMilliseconds;
            results.GetOrCreate("Newtonsoft.Json.JsonConvert.ToString").Add(t);

            sw = Stopwatch.StartNew();
            for (var i = 0; i < count; i++)
            {
                var s = cleanForJSON(testStr);
            }
            t = sw.ElapsedMilliseconds;
            results.GetOrCreate("Clive Paterson").Add(t);
        }

        Console.WriteLine(testStr);
        foreach (var result in results)
        {
            Console.WriteLine(result.Key + ": " + Math.Round(result.Value.Skip(1).Average()) + "ms");
        }
        Console.WriteLine();
    }

    Console.ReadLine();
}


2
String.Format("X", c);

वह सिर्फ आउटपुट: एक्स

इसके बजाय यह प्रयास करें:

string t = ((int)c).ToString("X");

sb.Append("\\u" + t.PadLeft(4, '0'));

2

मैं अच्छा वन-लाइनर हूं, JsonConvert का उपयोग करता हूं, जैसा कि दूसरों ने जोड़ा है, लेकिन जोड़े गए उद्धरणों और बैकस्लैश को हटाने के लिए प्रतिस्थापन जोड़ा है।

 var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);



0

मैंने इस्तेमाल करना चुना System.Web.Script.Serialization.JavaScriptSerializer

मेरे पास एक छोटे स्थिर सहायक वर्ग को निम्नानुसार परिभाषित किया गया है:

internal static partial class Serialization
{
    static JavaScriptSerializer serializer;
    
    static Serialization()
    {
        serializer = new JavaScriptSerializer();
        serializer.MaxJsonLength = Int32.MaxValue;
    }
    public static string ToJSON<T>(T obj)
    {
        return serializer.Serialize(obj);
    }
    public static T FromJSON<T>(string data)
    {
        if (Common.IsEmpty(data))
            return default(T);
        else
            return serializer.Deserialize<T>(data);
    }
}

कुछ भी सिलसिलेवार करने के लिए मैं सिर्फ फोन करता हूं Serialization.ToJSON(itemToSerialize)

मैं सिर्फ फोन करने के लिए deserialize Serialization.FromJSON<T>(jsonValueOfTypeT)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.