diff --git a/build/dependencies.props b/build/dependencies.props
index 574bb8be33e3953b5e55a5ac278906d8f35c1900..abcfc1eac6b8a98fbfd2652cb35b73c0d4bc1ad3 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -146,6 +146,8 @@
     <MicrosoftCodeAnalysisCSharpPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpPackageVersion>
     <MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>2.8.0</MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion>
     <MicrosoftCSharpPackageVersion>4.5.0</MicrosoftCSharpPackageVersion>
+    <MicrosoftDataODataPackageVersion>5.8.4</MicrosoftDataODataPackageVersion>
+    <MicrosoftDataServicesClientPackageVersion>5.8.4</MicrosoftDataServicesClientPackageVersion>
     <MicrosoftDiaSymReaderNativePackageVersion>1.7.0</MicrosoftDiaSymReaderNativePackageVersion>
     <MicrosoftDotNetArchivePackageVersion>0.2.0-beta-63019-01</MicrosoftDotNetArchivePackageVersion>
     <MicrosoftDotNetProjectModelPackageVersion>1.0.0-rc3-003121</MicrosoftDotNetProjectModelPackageVersion>
diff --git a/build/external-dependencies.props b/build/external-dependencies.props
index 37b2379b4285a2324dc5bf5c87cad0e95e7d8454..d3398e91c446d043d9027676f42788939e655a91 100644
--- a/build/external-dependencies.props
+++ b/build/external-dependencies.props
@@ -96,6 +96,8 @@
     <ExternalDependency Include="Microsoft.Build.Tasks.Core" Version="$(MicrosoftBuildTasksCorePackageVersion)" />
     <ExternalDependency Include="Microsoft.Build.Utilities.Core" Version="$(MicrosoftBuildUtilitiesCorePackageVersion)" />
     <ExternalDependency Include="Microsoft.Internal.AspNetCore.H2Spec.All" Version="$(MicrosoftInternalAspNetCoreH2SpecAllPackageVersion)" />
+    <ExternalDependency Include="Microsoft.Data.OData" Version="$(MicrosoftDataODataPackageVersion)" />
+    <ExternalDependency Include="Microsoft.Data.Services.Client" Version="$(MicrosoftDataServicesClientPackageVersion)" />
 
     <!-- Razor uses a custom version of roslyn packages -->
     <ExternalDependency Include="Microsoft.CodeAnalysis.Common" Version="$(MicrosoftCodeAnalysisCommonPackageVersion)" />
diff --git a/eng/Dependencies.props b/eng/Dependencies.props
index 2c0d8499f49d01eaf06a57b9aa1c9995046284b7..9ed0885937d2725fab0717f94cb7e0ec4b334d70 100644
--- a/eng/Dependencies.props
+++ b/eng/Dependencies.props
@@ -110,6 +110,8 @@ and are generated based on the last package release.
     <LatestPackageReference Include="IdentityServer4" Version="$(IdentityServer4PackageVersion)" />
     <LatestPackageReference Include="MessagePack" Version="$(MessagePackPackageVersion)" />
     <LatestPackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
+    <LatestPackageReference Include="Microsoft.Data.OData" Version="$(MicrosoftDataODataPackageVersion)" />
+    <LatestPackageReference Include="Microsoft.Data.Services.Client" Version="$(MicrosoftDataServicesClientPackageVersion)" />
     <LatestPackageReference Include="Moq" Version="$(MoqPackageVersion)" />
     <!-- This version is required by MSBuild tasks or Visual Studio extensions. -->
     <LatestPackageReference Include="Newtonsoft.Json" Version="9.0.1" Condition="'$(UseMSBuildJsonNet)' == 'true'" />
diff --git a/eng/PatchConfig.props b/eng/PatchConfig.props
index d16cb667c130bb17f0907d2df682243d396f12ca..3f12fb1a02310498e92912e630bd1f4bec358976 100644
--- a/eng/PatchConfig.props
+++ b/eng/PatchConfig.props
@@ -75,7 +75,9 @@ Later on, this will be checked using this condition:
   </PropertyGroup>
   <PropertyGroup Condition=" '$(VersionPrefix)' == '2.2.7' ">
     <PackagesInPatch>
+      Microsoft.AspNetCore.DataProtection.AzureStorage;
       Microsoft.AspNetCore.Hosting;
+      Microsoft.AspNetCore.SpaServices;
     </PackagesInPatch>
   </PropertyGroup>
 </Project>
diff --git a/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj b/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj
index d65f55a425f05b04e75df0199fef6955e6583c26..2e0d4c5dc48bcbf5de5edda523983ef9bdd0fc8b 100644
--- a/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj
+++ b/src/DataProtection/AzureStorage/src/Microsoft.AspNetCore.DataProtection.AzureStorage.csproj
@@ -1,16 +1,18 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <Description>Microsoft Azure Blob storrage support as key store.</Description>
+    <Description>Microsoft Azure Blob storage support as key store.</Description>
     <TargetFramework>netstandard2.0</TargetFramework>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;dataprotection;azure;blob</PackageTags>
+    <UseLatestPackageReferences>true</UseLatestPackageReferences>
   </PropertyGroup>
 
   <ItemGroup>
     <Reference Include="Microsoft.AspNetCore.DataProtection" />
     <Reference Include="WindowsAzure.Storage" />
+    <Reference Include="Microsoft.Data.OData" />
   </ItemGroup>
 
 </Project>
diff --git a/src/DataProtection/AzureStorage/test/Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj b/src/DataProtection/AzureStorage/test/Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj
index b6926a12d2b31d0902e1e601265dc4dd40f6cc28..01ac9713de8a66c7c8a3c90a3cce2c34a515eb3c 100644
--- a/src/DataProtection/AzureStorage/test/Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj
+++ b/src/DataProtection/AzureStorage/test/Microsoft.AspNetCore.DataProtection.AzureStorage.Tests.csproj
@@ -9,6 +9,8 @@
     <Reference Include="Microsoft.AspNetCore.DataProtection" />
     <Reference Include="Microsoft.AspNetCore.DataProtection.AzureStorage" />
     <Reference Include="Microsoft.Extensions.DependencyInjection" />
+    <Reference Include="Microsoft.Data.OData"/>
+    <Reference Include="Microsoft.Data.Services.Client"/>
   </ItemGroup>
 
 </Project>
diff --git a/src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs b/src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs
index 1a2e15635451e35386ef11848b9179063101064e..0cf02247a10270cd6d90395a123274bccba426f7 100644
--- a/src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs
+++ b/src/Middleware/SpaServices/src/Prerendering/RenderToStringResult.cs
@@ -1,6 +1,7 @@
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using System.Text;
+using System.Text.Encodings.Web;
 
 namespace Microsoft.AspNetCore.SpaServices.Prerendering
 {
@@ -49,12 +50,16 @@ namespace Microsoft.AspNetCore.SpaServices.Prerendering
 
             foreach (var property in Globals.Properties())
             {
-                stringBuilder.AppendFormat("window.{0} = {1};",
-                    property.Name,
-                    property.Value.ToString(Formatting.None));
+                var propertyNameJavaScriptString = JavaScriptEncoder.Default.Encode(property.Name);
+                var valueJson = property.Value.ToString(Formatting.None);
+                var valueJsonJavaScriptString = JavaScriptEncoder.Default.Encode(valueJson);
+
+                stringBuilder.AppendFormat("window[\"{0}\"] = JSON.parse(\"{1}\");",
+                    propertyNameJavaScriptString,
+                    valueJsonJavaScriptString);
             }
 
             return stringBuilder.ToString();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests/Microsoft.AspNetCore.SpaServices.Tests.csproj b/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests/Microsoft.AspNetCore.SpaServices.Tests.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..db1160878bb0fdee0a7eaac8dbab41ee0fb26fd0
--- /dev/null
+++ b/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests/Microsoft.AspNetCore.SpaServices.Tests.csproj
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFrameworks>netcoreapp2.0</TargetFrameworks>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Reference Include="Microsoft.AspNetCore.SpaServices" />
+  </ItemGroup>
+
+</Project>
diff --git a/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests/RenderToStringResultTest.cs b/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests/RenderToStringResultTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..77ce7a213c0ee724e1e5799e852fedb5c7ef1e2c
--- /dev/null
+++ b/src/Middleware/SpaServices/test/Microsoft.AspNetCore.SpaServices.Tests/RenderToStringResultTest.cs
@@ -0,0 +1,71 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Microsoft.AspNetCore.SpaServices.Prerendering;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Xunit;
+
+namespace Microsoft.AspNetCore.SpaServices.Tests
+{
+    public class RenderToStringResultTest
+    {
+        [Fact]
+        public void HandlesNullGlobals()
+        {
+            // Arrange
+            var renderToStringResult = new RenderToStringResult();
+            renderToStringResult.Globals = null;
+
+            // Act
+            var actualScript = renderToStringResult.CreateGlobalsAssignmentScript();
+
+            // Assert
+            Assert.Equal(string.Empty, actualScript);
+        }
+
+        [Fact]
+        public void HandlesGlobalsWithMultipleProperties()
+        {
+            // Arrange
+            var renderToStringResult = new RenderToStringResult();
+            renderToStringResult.Globals = ToJObject(new
+            {
+                FirstProperty = "first value",
+                SecondProperty = new[] { "Array entry 0", "Array entry 1" }
+            });
+
+            // Act
+            var actualScript = renderToStringResult.CreateGlobalsAssignmentScript();
+
+            // Assert
+            var expectedScript = @"window[""FirstProperty""] = JSON.parse(""\u0022first value\u0022"");" +
+                @"window[""SecondProperty""] = JSON.parse(""[\u0022Array entry 0\u0022,\u0022Array entry 1\u0022]"");";
+            Assert.Equal(expectedScript, actualScript);
+        }
+
+        [Fact]
+        public void HandlesGlobalsWithCorrectStringEncoding()
+        {
+            // Arrange
+            var renderToStringResult = new RenderToStringResult();
+            renderToStringResult.Globals = ToJObject(new Dictionary<string, object>
+            {
+                { "Va<l'u\"e", "</tag>\"'}\u260E" }
+            });
+
+            // Act
+            var actualScript = renderToStringResult.CreateGlobalsAssignmentScript();
+
+            // Assert
+            var expectedScript = @"window[""Va\u003Cl\u0027u\u0022e""] = JSON.parse(""\u0022\u003C\/tag\u003E\\\u0022\u0027}\u260E\u0022"");";
+            Assert.Equal(expectedScript, actualScript);
+        }
+
+        private static JObject ToJObject(object value)
+        {
+            return JsonConvert.DeserializeObject<JObject>(JsonConvert.SerializeObject(value));
+        }
+    }
+}