diff --git a/src/Middleware/Localization/Localization.slnf b/src/Middleware/Localization/Localization.slnf
new file mode 100644
index 000000000000..e4494b3619c2
--- /dev/null
+++ b/src/Middleware/Localization/Localization.slnf
@@ -0,0 +1,16 @@
+{
+ "solution": {
+ "path": "..\\Middleware.sln",
+ "projects": [
+ "Localization.Routing\\src\\Microsoft.AspNetCore.Localization.Routing.csproj",
+ "Localization.Routing\\test\\Microsoft.AspNetCore.Localization.Routing.Tests.csproj",
+ "Localization\\sample\\LocalizationSample.csproj",
+ "Localization\\src\\Microsoft.AspNetCore.Localization.csproj",
+ "Localization\\test\\FunctionalTests\\Microsoft.AspNetCore.Localization.FunctionalTests.csproj",
+ "Localization\\test\\UnitTests\\Microsoft.AspNetCore.Localization.Tests.csproj",
+ "Localization\\testassets\\LocalizationWebsite\\LocalizationWebsite.csproj",
+ "Localization\\testassets\\ResourcesClassLibraryNoAttribute\\ResourcesClassLibraryNoAttribute.csproj",
+ "Localization\\testassets\\ResourcesClassLibraryWithAttribute\\ResourcesClassLibraryWithAttribute.csproj"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp3.0.cs b/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp3.0.cs
index 599db4aca6c1..558921ba6b9d 100644
--- a/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp3.0.cs
+++ b/src/Middleware/Localization/ref/Microsoft.AspNetCore.Localization.netcoreapp3.0.cs
@@ -13,6 +13,7 @@ public static partial class ApplicationBuilderExtensions
public partial class RequestLocalizationOptions
{
public RequestLocalizationOptions() { }
+ public bool ApplyCurrentCultureToResponseHeaders { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public Microsoft.AspNetCore.Localization.RequestCulture DefaultRequestCulture { get { throw null; } set { } }
public bool FallBackToParentCultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
public bool FallBackToParentUICultures { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
diff --git a/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs b/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs
index c6ec3e1c0602..07277ecdd72b 100644
--- a/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs
+++ b/src/Middleware/Localization/src/RequestLocalizationMiddleware.cs
@@ -1,5 +1,5 @@
-// 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.
+// 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;
using System.Collections.Generic;
@@ -13,6 +13,7 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
+using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Localization
{
@@ -146,6 +147,11 @@ public async Task Invoke(HttpContext context)
SetCurrentThreadCulture(requestCulture);
+ if (_options.ApplyCurrentCultureToResponseHeaders)
+ {
+ context.Response.Headers.Add(HeaderNames.ContentLanguage, requestCulture.UICulture.Name);
+ }
+
await _next(context);
}
diff --git a/src/Middleware/Localization/src/RequestLocalizationOptions.cs b/src/Middleware/Localization/src/RequestLocalizationOptions.cs
index 16776364f0cc..95ca74fe32b5 100644
--- a/src/Middleware/Localization/src/RequestLocalizationOptions.cs
+++ b/src/Middleware/Localization/src/RequestLocalizationOptions.cs
@@ -84,6 +84,11 @@ public RequestCulture DefaultRequestCulture
///
public bool FallBackToParentUICultures { get; set; } = true;
+ ///
+ /// Gets or sets a value that determines if is applied to the response Content-Language header.
+ ///
+ public bool ApplyCurrentCultureToResponseHeaders { get; set; }
+
///
/// The cultures supported by the application. The will only set
/// the current request culture to an entry in this list.
diff --git a/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs b/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs
index 5f09115be2c8..15b00dfacfe2 100644
--- a/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs
+++ b/src/Middleware/Localization/test/FunctionalTests/LocalizationTest.cs
@@ -1,5 +1,5 @@
-// 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.
+// 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;
using System.Net;
@@ -14,6 +14,15 @@ namespace Microsoft.AspNetCore.Localization.FunctionalTests
{
public class LocalizationTest
{
+ [Fact]
+ public Task Localization_ContentLanguageHeader()
+ {
+ return RunTest(
+ typeof(StartupContentLanguageHeader),
+ "ar-YE",
+ "True ar-YE");
+ }
+
[Fact]
public Task Localization_CustomCulture()
{
diff --git a/src/Middleware/Localization/testassets/LocalizationWebsite/StartupContentLanguageHeader.cs b/src/Middleware/Localization/testassets/LocalizationWebsite/StartupContentLanguageHeader.cs
new file mode 100644
index 000000000000..849743184c1e
--- /dev/null
+++ b/src/Middleware/Localization/testassets/LocalizationWebsite/StartupContentLanguageHeader.cs
@@ -0,0 +1,49 @@
+// 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 System.Globalization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Localization;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Net.Http.Headers;
+
+namespace LocalizationWebsite
+{
+ public class StartupContentLanguageHeader
+ {
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddLocalization();
+ }
+
+ public void Configure(
+ IApplicationBuilder app)
+ {
+ app.UseRequestLocalization(new RequestLocalizationOptions
+ {
+ DefaultRequestCulture = new RequestCulture("en-US"),
+ SupportedCultures = new List()
+ {
+ new CultureInfo("ar-YE")
+ },
+ SupportedUICultures = new List()
+ {
+ new CultureInfo("ar-YE")
+ },
+ ApplyCurrentCultureToResponseHeaders = true
+ });
+
+ app.Run(async (context) =>
+ {
+ var hasContentLanguageHeader = context.Response.Headers.ContainsKey(HeaderNames.ContentLanguage);
+ var contentLanguage = context.Response.Headers[HeaderNames.ContentLanguage].ToString();
+
+ await context.Response.WriteAsync(hasContentLanguageHeader.ToString());
+ await context.Response.WriteAsync(" ");
+ await context.Response.WriteAsync(contentLanguage);
+ });
+ }
+ }
+}
\ No newline at end of file