Is there a standard way to encode a .NET string into JavaScript string for use in MS Ajax?

39,150

Solution 1

Have you had a look at HttpUtility.JavaScriptStringEncode?

Solution 2

A probem with this function is that it doesn't encode characters that are typically out-of-band in encapsulating HTML... so you'd have trouble if you tried to include a string with " inside an attribute value, or if you had a string with the sequence </script> inside a script element. That could lead to script-injection and XSS.

You could add:

            case '<':
                sb.Append("\\x3C");
                break;
            case '"':
                sb.Append("\\x22");
                break;
            case '&':
                sb.Append("\\x26");
                break;

In general it would probably be better to use a standard JSON encoder than brew your own JS string literal encoder. This will allow you to pass any simple datatype to JS rather than just strings.

In .NET 3.5 you get JavaScriptSerializer, however note that whilst this does encode < to \u003C (so the output will be suitable for use in a <script> element), it doesn't encode & or ", so HTML-escaping would be needed to include such content in an attribute value and a CDATA wrapper would be needed for XHTML script elements.

(In common with many JSON encoders, it also fails to encode the U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR characters. The above code does, due to escaping all non-ASCII characters. This causes ‘unterminated string literal’ errors when these characters are included in a JS string literal, because JavaScript unhelpfully treats them the same as an ASCII newline.)

Solution 3

This is an old thread, but you may be interested to know about the Microsoft AntiXSS library which has a Javascript encode method which works for .Net 2 onwards.

http://msdn.microsoft.com/en-gb/security/aa973814.aspx

Share:
39,150
Rich Andrews
Author by

Rich Andrews

Updated on January 20, 2020

Comments

  • Rich Andrews
    Rich Andrews over 4 years

    I'm trying to pass the output of a SQL Server exception to the client using the RegisterStartUpScript method of the MS ScriptManager in .NET 3.5. This works fine for some errors but when the exception contains single quotes the alert fails.

    I dont want to only escape single quotes though. Is there a standard function I can call to escape any special chars for use in JavaScript?

    string scriptstring = "alert('" + ex.Message + "');";         
    ScriptManager.RegisterStartupScript(this, this.GetType(), "Alert", scriptstring , true);
    

    EDIT:

    Thanks @tpeczek, the code almost worked for me :) but with a slight amendment (the escaping of single quotes) it works a treat.

    I've included my amended version here...

    public class JSEncode
    {
        /// <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 '\\':
                        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();
        }
    }
    

    As mentioned below - original source: here

  • Rich Andrews
    Rich Andrews over 13 years
    Upvoted because its a great answer - only works in .NET 4 though
  • bdukes
    bdukes over 13 years
    Great write-up. Note that JavaScriptSerializer is also available in .NET 2 via the ASP.NET AJAX 1.0 out-of-band release (microsoft.com/downloads/en/…).
  • Luke
    Luke over 11 years
    I think that when there is a framework function for a specific task (like this) it is often more reliable and accurate than the do-it-yourself ones, so it's better stick with it..
  • rdans
    rdans over 10 years
    This article shows how to implement it pre .NET 4 briancaos.wordpress.com/2012/05/16/…
  • Rich Andrews
    Rich Andrews about 10 years
    @eddy, the question states .NET 3.5, not 4 and this code only works in 4+. That's why it is not the answer.
  • R. Salisbury
    R. Salisbury over 8 years
    Note: For those looking for a way to encode international characters into escaped sequences, this will not work. See this question for a solution to that problem.
  • Martin Brown
    Martin Brown about 8 years
    In that case you wouldn't you use HttpUtility.HtmlAttributeEncode(HttpUtility.JavaScriptString‌​Encode(unencodedStri‌​ng)) or HttpUtility.HtmlEncode(HttpUtility.JavaScriptStringEncode(un‌​encodedString)) depending upon the context?
  • Amit Patil
    Amit Patil about 8 years
    @MartinBrown: you could use either of those to inject into JS-in-HTML-attribute, yes (although it's generally a bad idea to be doing that). The HtmlEncode and HtmlAttributeEncode methods are curiously named; it seems like one ought to work better for attribute values and one ought to work better for text content, but there is no such distinction in practice judging by the referencesource. They are just two arbitrarily-differently-implemented HTML encoders.
  • Alas
    Alas almost 8 years
    i read that the question is for 3.5 but still this should be the correct answer as 3.5 is starting to be obsolete and this is the first result when i google "c# encode string for javascript alert", maybe add the function code in case you use 3.5 or lower
  • deniz
    deniz almost 7 years
    The entirety of the MSDN description for that method is "Encodes a string." Is there a more complete description of what the method actually does?
  • Broots Waymb
    Broots Waymb over 5 years
    This link is no longer helpful. Are you able to update it?
  • DomBat
    DomBat over 5 years
    That library was pretty old. Use this System.Web.Security.AntiXss perhaps?
  • Jordan Rieger
    Jordan Rieger almost 2 years
    Note that this method also correctly handles <script> tags within the string, encoding them to be non-active strings and avoiding XSS.