I'mlookingatapieceofcodethat'sacustomcontrolthatembedsabitofJavaScriptintoapage.PartofthisJavaScriptisgeneratingsomestaticstringtextdirectlyintothepage.I'vebeenrunningthiscodeforawhilenowaspartofanapplicationI'mworkingonwithacustomer.
ButacoupleofdaysagoIranintoacoupleofproblemswiththiscontrolandasitturnsouttheproblemisthattheJavaScriptstringsembeddedintotheHTMLstreamaren'tproperlyencoded.Thecodeusedissomethinglikethis(grosslysimplified):
stringmarkup="SomeText";stringscript=@"embedHtml("{0}");functionembedHtml(result){{alert(result)}}";this.Page.ClientScript.RegisterStartupScript(typeof(Page),"embedHtml",string.Format(script,markup),true);Theideaisthatthecodegetssometextthatcomesfromtheserversideandgetsembeddedintothepage.Theclientscriptbasicallytakestheembeddedstringanddisplaysitwhenthepageloads(therealthingembedsabunchofHTMLintothepageindynamicpositionsbutsameidea).
Canyouspottheproblem
Actuallythisisallfineanddandywiththecodeabove.Itworksfine.
Butitstartsbecomingaproblemifthetextthatyouareembeddingcontainsspecialcharacters.Saythestringthatyouembedcontainscarriagereturns,extendedcharactersormaybemorepertinently-doublequotes(whichiswhatblewmycodeuporiginallynotsurprisinglysincetheembeddedstringcontainedHTML).
ForexampletakethisC#stringassignmentontheserver:
stringmarkup="Hello\"Rick\"\r\nRockOn";whichwhengeneratedintotheclientsidewiththecodeaboveresultsin:
embedHtml("Hello"Rick"RockOn");whichclearlyisgoingtocauseaJavaScripterrorwhenthepageloads.
Theproblemisthatusing
embedHtml("{0}");or
embedHtml('{0}');isastringliteralandithastobeembeddedintothepageproperlyorelsecodewillblowupsporadicallyascertaincharactersarepartofthestringsembedded.
Thefixforthisistoencodethestringtoembed.TheeasiestwaytouseproperJavaScriptstringencodingistouseJSONencodingonthestringandyoucandothatwiththefollowingcode:
///
Sonowwecanchangethecodeto:
stringmarkup=wwWebUtils.EncodeJsString("Hello\"Rick\"\r\nRockOn");stringscript=@"embedHtml({0});functionembedHtml(result){{alert(result)}}";this.Page.ClientScript.RegisterStartupScript(typeof(Page),"embedHtml",string.Format(script,markup),true);Andvoila-thatworkscorrectly.TheembeddedstringintheJavaScriptnowlookslikethis:
"Hello\"Rick\"\r\nRockOn"
NotethattheembedHtml({0})codehasremovedthequotesaroundtheformat/replaceparameterasEncodeJsStringwillcreatethestringwithquotesarounditsothere'snoambiguityaboutwhichstringdelimiterstouse.Thiscanalsoreducethecomplexityofcodethatrequiresnestedstringexpressions.
Thissamelogicappliesifyouusescriptexpressionsinsideofapage:
alert(<%=wwWebUtils.EncodeJsString("MynameisSam\r\nRollon")%>);OneplacewhereI'veactuallyusedthisalotinthepastisforclientscriptlocalization.Ifyoudosomethinglikethisforexample:
alert(<%=HttpContext.GetGlobalResourceObject("Resources","WarrantyDetail")%>);youcanrunintothesameencodingproblemsandthiscodeshouldbechangedto:
alert(<%=wwWebUtils.EncodeJsString(HttpContext.GetGlobalResourceObject("Resources","WarrantyDetail"))%>);Iknowalotofpeopletrulydisdain'legacy'ASPclassicscripttags,butinsomecases-localizationespecially-theyaretheeasiestandmostreadablewaytoaccomplishthetask.OfcoursethesamerulescouldbeimpliedwithaLabelorLiteralcontrolandencodingthetextexplicitlyincode.
I'verunintothisproblemonafewoccasionsmyselfandIseeitfrequentlyinotherpeople'scode.WhileitmaynotbeallthatcommontoembedstringliteralsintoJavaScriptwhenyoudoneedtodoitit'sveryimportanttoencodethestring.
It'stheselittledetailsthatareeasytomisswhenworkingwithJavaScriptsoI'dthoughtIpassthisonealong...Hopethishelpssomebodyout.
IsthereanequivalentmethodtoJavaScriptStringEncode()inthenewAspNetCorepackagesIneedthisfunctionalitybutwanttoavoidusingoldAspNetSystem.Webdependencies.