- You can render values directly to JavaScript
<script>
in your view/HTML/page files.
- And then any JavaScript (with or without Knockout, jQuery, React, Redux, AngularJS, Angular2+, whatever) can access those values immediately.
- IMPORTANT: Be sure to correctly JS-encode (not HTML-encode!) C#/.NET
String
values when rendering them as JavaScript string literals! ...otherwise backslashes and quotes will be rendered literally which will break your rendered <script>
element and likely introduce significant XSS vulnerabilities.
In ASP.NET 4.x, use HttpUtility.JavaScriptStringEncode
to ensure C#/.NET string
values are correctly and safely encoded to JavaScript strings.
In ASP.NET Core you can continue to use HttpUtility.JavaScriptStringEncode
(in the now almost empty System.Web.dll
System.Web.HttpUtility.dll
in .NET Core 2.x or later) however now the preferred API in .NET is System.Text.Encodings.Web.JavaScriptEncoder
's Encode
method (tip: use JavaScriptEncoder.Default.Encode
).
Note that HttpUtility.JavaScriptStringEncode
can optionally add delimiting quotes for you, but System.Text.Encodings.Web.JavaScriptEncoder
never renders outer quotes.
For Razor .cshtml
in ASP.NET MVC and ASP.NET 4.x WebPages:
(I assume your <head>
is in _Layout.cshtml
)
@using System.Configuration
@using System.Web.Configuration
<html>
<head>
<script>
var myAppSetting = '@( HttpUtility.JavaScriptStringEncode( WebConfigurationManager.AppSettings["myAppSetting"], addDoubleQuotes: false ) )';
</script>
</head>
<body>
</body>
For ASP.NET WebForms .aspx
/.ascx
/.master
and/or ASP.NET MVC 1.x and 2.x using the WebForms ASPX View Engine:
- (I assume your
<head>
is in Layout.master
)
- Use
<%=
instead of <%:
to render directly, btw, as we don't want to HTML-encode this JavaScript string literal.
<%@ Import Namespace="System.Configuration" %>
<%@ Import Namespace="System.Web.Configuration" %>
<html>
<head>
<script>
var myAppSetting = '<%= HttpUtility.JavaScriptStringEncode( WebConfigurationManager.AppSettings["myAppSetting"], addDoubleQuotes: false ) %>';
</script>
</head>
<body>
</body>
For ASP.NET Core MVC's Razor .cshtml
views:
- Use
@inject IConfiguration
to get immediate access to .NET Core's appSettings.
- You can use either
HttpUtility.JavaScriptStringEncode(...)
or System.Text.Encodings.Web.JavaScriptEncoder.Default.Encode(...)
in ASP.NET Core (including .NET 6).
- Don't forget outer-quotes!
- Use
Html.Raw()
to render the JS literal string. Do not use the normal Razor "write" syntax (i.e. @( value )
or @value
) because it will HTML-encode your JavaScript, which you don't want.
- Like so:
@using System.Text.Encodings.Web
@inject IConfiguration Config
<html>
<head>
<script>
var myAppSetting = '@Html.Raw( JavaScriptEncoder.Default.Encode( this.Config.GetValue<String>("appSettings:myAppSetting") )';
</script>
</head>
<body>
</body>
Note that if you want null
values from your appSettings.json to appear as JavaScript null
literals then you need to do that manually - you can use a @functions
method to handle this, like so:
@using System.Text.Encodings.Web
@using Microsoft.AspNetCore.Html
@inject IConfiguration Config
@functions{
public HtmlString GetAppSettingJSString( String name )
{
if( name is null ) throw new ArgumentNullException(nameof(name));
String? appSettingValue = this.Config.GetValue<String?>( "appSettings:" + name );
return ToJSStringLiteral( appSettingValue );
}
private static readonly HtmlString _nullLiteral = new HtmlString( "null" );
public static HtmlString ToJSStringLiteral( String? value )
{
if( value is null ) return _nullLiteral;
String jsStringLiteralChars = JavaScriptEncoder.Default.Encode( value );
return new HtmlString( '"' + jsStringLiteralChars + '"' );
}
}
<html>
<head>
<script>
var myAppSetting = @Html.Raw( this.GetAppSettingJSString( "myAppSetting" ) );
</script>
</head>
<body>
</body>
So now the <script>
above will be rendered as either this:
<script>
var myAppSetting = "foobarbaz";
</script>
...or this:
<script>
var myAppSetting = null;
</script>
Any script (except ES Modules, I think?) can access myAppSetting
via the implicit global
(aka window
) object, as all top-level var
declarations become global properties.
So like so:
<script>
document.addEventListener( 'DOMContentLoaded', function() {
alert( "myAppSetting: \"" + window.myAppSetting + "\"" );
} );
</script>