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