// 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.usingSystem;usingSystem.Collections.Generic;usingSystem.Globalization;usingSystem.Threading;namespaceMicrosoft.AspNet.Mvc.Razor{/// <summary>/// A <see cref="IViewLocationExpander"/> that adds the language as an extension prefix to view names. Language/// that is getting added as extension prefix comes from <see cref="Microsoft.AspNet.Http.HttpContext"/>./// </summary>/// <example>/// For the default case with no areas, views are generated with the following patterns (assuming controller is/// "Home", action is "Index" and language is "en")/// Views/Home/en/Action/// Views/Home/Action/// Views/Shared/en/Action/// Views/Shared/Action/// </example>publicclassLanguageViewLocationExpander:IViewLocationExpander{privateconststring ValueKey ="language";privateLanguageViewLocationExpanderFormat _format;/// <summary>/// Instantiates a new <see cref="LanguageViewLocationExpander"/> instance./// </summary>publicLanguageViewLocationExpander():this(LanguageViewLocationExpanderFormat.Suffix){}/// <summary>/// Instantiates a new <see cref="DefaultTagHelperActivator"/> instance./// </summary>/// <param name="format">The <see cref="LanguageViewLocationExpanderFormat"/>.</param>publicLanguageViewLocationExpander(LanguageViewLocationExpanderFormat format){
_format = format;}/// <inheritdoc />publicvoidPopulateValues(ViewLocationExpanderContext context){if(context ==null){thrownewArgumentNullException(nameof(context));}// Using CurrentUICulture so it loads the locale specific resources for the views.#if NET451
context.Values[ValueKey]= Thread.CurrentThread.CurrentUICulture.Name;#else
context.Values[ValueKey]= CultureInfo.CurrentUICulture.Name;#endif}/// <inheritdoc />publicvirtualIEnumerable<string>ExpandViewLocations(ViewLocationExpanderContext context,IEnumerable<string> viewLocations){if(context ==null){thrownewArgumentNullException(nameof(context));}if(viewLocations ==null){thrownewArgumentNullException(nameof(viewLocations));}stringvalue;
context.Values.TryGetValue(ValueKey,outvalue);if(!string.IsNullOrEmpty(value)){CultureInfo culture;try{
culture =newCultureInfo(value);}catch(CultureNotFoundException){return viewLocations;}returnExpandViewLocationsCore(viewLocations, culture);}return viewLocations;}privateIEnumerable<string>ExpandViewLocationsCore(IEnumerable<string> viewLocations,CultureInfo cultureInfo){foreach(var location in viewLocations){var temporaryCultureInfo = cultureInfo;while(temporaryCultureInfo != temporaryCultureInfo.Parent){if(_format == LanguageViewLocationExpanderFormat.SubFolder){yieldreturn location.Replace("{0}", temporaryCultureInfo.Name +"/{0}");}else{yieldreturn location.Replace("{0}","{0}."+ temporaryCultureInfo.Name);}
temporaryCultureInfo = temporaryCultureInfo.Parent;}yieldreturn location;}}}}
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.usingSystem;usingSystem.Collections.Generic;usingMicrosoft.AspNet.Mvc;usingMicrosoft.AspNet.Mvc.Razor;namespaceRazorWebSite{/// <summary>/// A <see cref="IViewLocationExpander"/> that replaces adds the language as an extension prefix to view names./// </summary>/// <example>/// For the default case with no areas, views are generated with the following patterns (assuming controller is/// "Home", action is "Index" and language is "en")/// Views/Home/en/Action/// Views/Home/Action/// Views/Shared/en/Action/// Views/Shared/Action/// </example>publicclassLanguageViewLocationExpander:IViewLocationExpander{privateconststring ValueKey ="language";privatereadonlyFunc<ActionContext,string> _valueFactory;/// <summary>/// Initializes a new instance of <see cref="LanguageViewLocationExpander"/>./// </summary>/// <param name="valueFactory">A factory that provides tbe language to use for expansion.</param>publicLanguageViewLocationExpander(Func<ActionContext,string> valueFactory){
_valueFactory = valueFactory;}/// <inheritdoc />publicvoidPopulateValues(ViewLocationExpanderContext context){varvalue=_valueFactory(context.ActionContext);if(!string.IsNullOrEmpty(value)){
context.Values[ValueKey]=value;}}/// <inheritdoc />publicvirtualIEnumerable<string>ExpandViewLocations(ViewLocationExpanderContext context,IEnumerable<string> viewLocations){stringvalue;if(context.Values.TryGetValue(ValueKey,outvalue)){returnExpandViewLocationsCore(viewLocations,value);}return viewLocations;}privateIEnumerable<string>ExpandViewLocationsCore(IEnumerable<string> viewLocations,stringvalue){foreach(var location in viewLocations){yieldreturn location.Replace("{0}",value+"/{0}");yieldreturn location;}}}}
LanguageViewLocationExpander.cs// 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;using Sy