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)); + } + } +}