I ended up doing something which I think it more robust. In master page I added this:
public Dictionary<string, object> JavaScriptVars { get; set; }
Then I append the result of this function to the page:
public string GetJavaScriptVars()
{
if (JavaScriptVars.Count == 0) return null;
StringBuilder sb = new StringBuilder();
sb.Append("<script>");
System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
int i = 0;
foreach (string s in JavaScriptVars.Keys)
{
if (i == 0)
sb.Append("var ");
sb.Append(s + "=");
object o = JavaScriptVars[s];
if (o is System.Collections.Specialized.NameValueCollection)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (string key in ((System.Collections.Specialized.NameValueCollection)o).Keys)
dict[key] = ((System.Collections.Specialized.NameValueCollection)o)[key];
o = dict;
}
sb.Append(serializer.Serialize(o));
sb.Append(i == JavaScriptVars.Count - 1 ? ";" : ",");
i++;
}
sb.Append("</script>");
return sb.ToString();
}
So now I can do this:
JavaScriptVars["Name"] = "John"; //string
JavaScriptVars["Age"] = 32; //int
JavaScriptVars["Hobbies"] = new string[] { "Sewing", "Hiking" }; //array
and in my final page, I get:
<script>
var Name='John',Age=32,Hobbies=["Sewing", "Hiking"];
</script>
So now I have a robust way to pass values with types correctly managed to the page without script blocks or labels.
var a = <%= a %>;is basically the standard way of doing it. Don't overthink; it's simple, makes sense and is readable.