/// <summary>
        /// Async method that listens for events in the request execution pipeline. Will catch <see cref="CultureNotFoundException"/> and return instructions to redirect the request in the response.
        /// </summary>
        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (CultureNotFoundException)
            {
                if (context.Response.HasStarted)
                {
                    throw;
                }

                var request = context.Request;
                var parts   = request.Path.Value.Split('/');

                parts[_routeCultureOptions.Value.CultureParameterIndex] = CultureInfo.CurrentCulture.Name;

                var newPath = (string.IsNullOrWhiteSpace(_responsePath))
                    ? string.Join("/", parts)
                    : _responsePath;
                var newUrl = UrlUtilities.ReplacePath(request, newPath);

                _logger.LogRequestCultureNotFoundRedirect(newPath);

                context.Response.Clear();
                context.Response.StatusCode = _statusCode;
                context.Response.Headers[HeaderNames.Location] = newUrl;

                return;
            }
        }
        /// <summary>
        /// Checks that the <see cref="RouteCultureOptions.LanguageLocaleMap"/> contains the current request culture. If yes, redirects to a URL containing the matching locale.
        /// </summary>
        /// <param name="context">A <see cref="RewriteContext"/> context</param>
        public void ApplyRule(RewriteContext context)
        {
            var request = context.HttpContext.Request;
            var parts   = request.Path.Value.Split('/');
            var culture = parts[_routeCultureOptions.Value.CultureParameterIndex];

            if (!_languageLocaleMap.ContainsKey(culture))
            {
                context.Result = RuleResult.ContinueRules;
                return;
            }

            foreach (var map in _languageLocaleMap)
            {
                if (map.Key == culture)
                {
                    parts[_routeCultureOptions.Value.CultureParameterIndex] = map.Value;
                    break;
                }
            }

            var newPath = string.Join("/", parts);
            var newUrl  = UrlUtilities.ReplacePath(request, newPath);

            var response = context.HttpContext.Response;

            response.StatusCode = _statusCode;
            response.Headers[HeaderNames.Location] = newUrl;
            context.Result = RuleResult.EndResponse;
        }
        /// <summary>
        /// Assesses if request contains a culture parameter. If not, appends current culture name to path and redirects.
        /// </summary>
        /// <remarks>
        /// The redirect URL respects the <see cref="RouteOptions"/> setting as regards whether a trailing slash should be appeneded to the generated URL
        /// </remarks>
        public Task Invoke(HttpContext context)
        {
            var request    = context.Request;
            var parameters = request.Path.Value.Split('/');
            var culture    = parameters[_routeCultureOptions.Value.CultureParameterIndex];

            if (!string.IsNullOrWhiteSpace(culture))
            {
                return(_next(context));
            }

            var newPath = $"/{CultureInfo.CurrentCulture.Name}";

            if (_routeOptions.Value.AppendTrailingSlash)
            {
                newPath += "/";
            }

            var newUrl = UrlUtilities.ReplacePath(request, newPath);

            _logger.LogRequiredCultureRedirect(newPath);

            context.Response.Clear();
            context.Response.StatusCode = _statusCode;
            context.Response.Headers[HeaderNames.Location] = newUrl;

            return(_next(context));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Similar to the GetDisplayUrl() method that extends <see cref="HttpRequest"/>,
        /// but allows you to specify a new parameter that will replace an existing parameter
        /// </summary>
        /// <remarks>Useful for obtaining URLs with alternate culture parameter</remarks>
        /// <param name="request">A <see cref="HttpRequest"/> object</param>
        /// <param name="parameterIndex">The index of the URL parameter to be replaced</param>
        /// <param name="replacementParameter">The new replacement parameter</param>
        /// <returns>The new display URL</returns>
        public static string GetDisplayUrl(this HttpRequest request, int parameterIndex, string replacementParameter)
        {
            var parameters = request.Path.Value.Split('/');

            if (parameters is null || parameters.Length <= 1)
            {
                return(request.GetDisplayUrl());
            }

            parameters[parameterIndex] = replacementParameter;

            var newPath = string.Join("/", parameters);

            return(UrlUtilities.ReplacePath(request, newPath));
        }