public override async Task Invoke(IOwinContext context) { var workContext = _container.Resolve <WorkContext>(); if (workContext.RequestUrl != null) { var currentStoreId = workContext.CurrentStore != null ? workContext.CurrentStore.Id : "-"; var currentCultureName = workContext.CurrentStore != null ? workContext.CurrentLanguage.CultureName : "en-US"; var normalizedPath = new PathString(); //add store to path normalizedPath = normalizedPath.Add(new PathString("/" + currentStoreId)); //add language to path normalizedPath = normalizedPath.Add(new PathString("/" + currentCultureName)); //add remaining path part without store and language var requestPath = context.Request.Path.Value; requestPath = Regex.Replace(requestPath, "/" + currentStoreId + "/?", "/", RegexOptions.IgnoreCase); requestPath = Regex.Replace(requestPath, "/" + currentCultureName + "/?", "/", RegexOptions.IgnoreCase); normalizedPath = normalizedPath.Add(new PathString(requestPath)); context.Request.Path = normalizedPath; //http://stackoverflow.com/questions/28252230/url-rewrite-in-owin-middleware var httpContext = context.Environment["System.Web.HttpContextBase"] as System.Web.HttpContextWrapper; if (httpContext != null) { httpContext.RewritePath("~" + normalizedPath.Value); } } await Next.Invoke(context); }
/// <summary> /// Maps the IDP endpoints to <paramref name="path"/>. /// </summary> /// <param name="builder">The <see cref="IEndpointRouteBuilder"/> to map the endpoints to.</param> /// <param name="path">The base path to map the endpoints to.</param> /// <returns>The <see cref="IEndpointRouteBuilder"/> instance so that additional calls can be chained.</returns> public static IEndpointRouteBuilder MapSaml2pIdentityProvider(this IEndpointRouteBuilder builder, PathString path) { var options = builder.ServiceProvider.GetRequiredService <IOptions <Saml2pOptions> >().Value; builder.Map(path.Add(options.AcceptPath), builder.CreateApplicationBuilder().UseAcceptSsoEndpoint(path).Build()).WithMetadata(new HttpMethodMetadata(new[] { HttpMethods.Get, HttpMethods.Post })); builder.Map(path.Add(options.InitiatePath), builder.CreateApplicationBuilder().UseInitiateSsoEndpoint(path).Build()).WithMetadata(new HttpMethodMetadata(new[] { HttpMethods.Get, HttpMethods.Post }));; builder.Map(path.Add(options.CompletePath), builder.CreateApplicationBuilder().UseCompleteSsoEndpoint(path).Build()).WithMetadata(new HttpMethodMetadata(new[] { HttpMethods.Get, HttpMethods.Post }));; return(builder); }
/// <summary> /// Maps the IDP endpoints to <paramref name="path"/>. /// </summary> /// <param name="builder">The <see cref="IApplicationBuilder"/> to map the endpoints to.</param> /// <param name="path">The base path to map the endpoints to.</param> /// <returns>The <see cref="IApplicationBuilder"/> instance so that additional calls can be chained.</returns> public static IApplicationBuilder UseSaml2pIdentityProvider(this IApplicationBuilder builder, PathString path) { var options = builder.ApplicationServices.GetRequiredService <IOptions <Saml2pOptions> >().Value; return(builder .Map(path.Add(options.AcceptPath), b => b.UseAcceptSsoEndpoint(path)) .Map(path.Add(options.InitiatePath), b => b.UseInitiateSsoEndpoint(path)) .Map(path.Add(options.CompletePath), b => b.UseCompleteSsoEndpoint(path)) ); }
public async Task InvokeAsync(HttpContext httpContext) { if (httpContext.Request.Path.StartsWithSegments(basePath.Add(ScheduleEndpointPaths.DASHBOARD_PATH))) { var schedulerFactory = (ISchedulerFactory)httpContext.RequestServices.GetService(typeof(ISchedulerFactory)); var jobName = httpContext.Request.Query["jobName"]; var response = await GetData(schedulerFactory, jobName); var razorViewEngine = (IRazorViewEngine)httpContext.RequestServices.GetService(typeof(IRazorViewEngine)); var tempDataProvider = (ITempDataProvider)httpContext.RequestServices.GetService(typeof(ITempDataProvider)); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var path = "\\Middlewares\\Schedule\\Models\\Schedules.cshtml"; var view = razorViewEngine.GetView(null, path, true).View; var html = string.Empty; using (var output = new StringWriter()) { var viewData = new ViewDataDictionary <List <ScheduleResponse> >(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = response }; viewData.Add("JobPath", basePath.Add(JobEndpointPaths.DASHBOARD_PATH)); viewData.Add("TriggerPath", basePath.Add(TriggerEndpointPaths.API_PATH)); var viewContext = new ViewContext( actionContext, view, viewData, new TempDataDictionary(actionContext.HttpContext, tempDataProvider), output, new HtmlHelperOptions()); await view.RenderAsync(viewContext); html = output.ToString(); } httpContext.Response.ContentType = "text/html"; await httpContext.Response.WriteAsync(html); } else { await _next(httpContext); } }
/// <summary> /// Handles all requests from this point in the middleware chain by returning /// the default page for the Single Page Application (SPA). /// /// This middleware should be placed late in the chain, so that other middleware /// for serving static files, MVC actions, etc., takes precedence. /// </summary> /// <param name="app">The <see cref="IApplicationBuilder"/>.</param> /// <param name="publicPath"> /// The URL path, relative to your application's <c>PathBase</c>, from which the /// SPA files are served. /// /// For example, if your SPA files are located in <c>wwwroot/dist</c>, then /// the value should usually be <c>"dist"</c>, because that is the URL prefix /// from which browsers can request those files. /// </param> /// <param name="defaultPage"> /// Optional. If specified, configures the path (relative to <paramref name="publicPath"/>) /// of the default page that hosts your SPA user interface. /// If not specified, the default value is <c>"index.html"</c>. /// </param> /// <param name="configure"> /// Optional. If specified, configures hosting options and further middleware for your SPA. /// </param> public static void UseSpa( this IApplicationBuilder app, string publicPath, string defaultPage = null, Action <ISpaBuilder> configure = null) { if (string.IsNullOrEmpty(publicPath)) { throw new ArgumentException("Cannot be null or empty", nameof(publicPath)); } if (string.IsNullOrEmpty(defaultPage)) { defaultPage = "index.html"; } var publicPathString = new PathString(publicPath); var defaultFilePath = publicPathString.Add(new PathString("/" + defaultPage)); // Support client-side routing by mapping all requests to the SPA default file RewriteAllRequestsToServeDefaultFile(app, publicPathString, defaultFilePath); // Allow other SPA configuration. This could add other middleware for // serving the default file, such as prerendering or Webpack/AngularCLI middleware. configure?.Invoke(new DefaultSpaBuilder(app, publicPath, defaultFilePath)); // If the default file wasn't served by any other middleware, // serve it as a static file from disk AddTerminalMiddlewareForDefaultFile(app, defaultFilePath); }
public async Task Post_TwoPlayerMatch_Success() { var apiPath = new PathString("https://mthcricket01api.azurewebsites.net/api/"); var routePath = new PathString("/matches/"); var path = apiPath.Add(routePath); var query = QueryString.Create(new[] { new KeyValuePair <string, string>("player", "P1"), new KeyValuePair <string, string>("player", "P2"), new KeyValuePair <string, string>("max_rounds", "20"), new KeyValuePair <string, string>("scoring_mode", "Standard") }); //var client = _clientFactory.CreateClient(); var request = new DefaultHttpRequest().Request; var requestFeature = request.HttpContext.Features.Get <IHttpRequestFeature>(); requestFeature.QueryString = query; HttpRequestMessage request = new HttpRequestMessage { Method = HttpMethods.Post, Path = path, Query = query, Body = "", }; var response = await client.PostAsync(request); var expected = File.ReadAllText(@"testData/TwoPlayerMatch_Expected.json"); Assert.Equal(expected, response.Value); }
/// <summary> /// Instantiates the base query middleware with an optional pointer to /// the next component. /// </summary> /// <param name="next"> /// An optional pointer to the next component. /// </param> /// <param name="queryExecutor"> /// A required query executor resolver. /// </param> /// <param name="resultSerializer"> /// </param> /// <param name="options"> /// </param> protected QueryMiddlewareBase( RequestDelegate next, IPathOptionAccessor options, OwinContextAccessor owinContextAccessor, IServiceProvider services) : base(next) { if (options == null) { throw new ArgumentNullException(nameof(options)); } _accessor = owinContextAccessor; _services = services ?? throw new ArgumentNullException(nameof(services)); if (options.Path.Value.Length > 1) { var path1 = new PathString(options.Path.Value.TrimEnd('/')); PathString path2 = path1.Add(new PathString("/")); _isPathValid = ctx => ctx.IsValidPath(path1, path2); } else { _isPathValid = ctx => ctx.IsValidPath(options.Path); } }
/// <summary> /// Converts a virtual (relative) path to an application absolute path. /// </summary> /// <param name="path"></param> /// <returns></returns> public string Content(string path) { if (string.IsNullOrEmpty(path)) { return(null); } //if this is a protocol-relative/protocol-less uri, then we need to add the protocol for the remaining // logic to work properly if (path.StartsWith("//")) { var scheme = _siteInfo.GetBaseUrl().Scheme; return(Regex.Replace(path, @"^\/\/", string.Format("{0}{1}", scheme, Constants.SchemeDelimiter))); } //This code is taken from the UrlHelper code ... which shouldn't need to be tucked away in there // since it is not dependent on the ActionContext if (path[0] == 126) { PathString pathBase = _siteInfo.GetBasePath(); return(pathBase.Add(new PathString(path.Substring(1))).Value); } return(path); }
public MiniProfilerActionFilter() { var basePath = new PathString( StackExchange.Profiling.MiniProfiler.Settings.RouteBasePath.Replace("~/", "/")); resultsLink = basePath.Add(new PathString("/results-index")); }
/// <summary> /// Instantiates the base query middleware with an optional pointer to /// the next component. /// </summary> /// <param name="next"> /// An optional pointer to the next component. /// </param> /// <param name="queryExecutor"> /// A required query executor resolver. /// </param> /// <param name="resultSerializer"> /// </param> /// <param name="options"> /// </param> protected QueryMiddlewareBase( RequestDelegate next, IQueryExecutor queryExecutor, IQueryResultSerializer resultSerializer, QueryMiddlewareOptions options) #if ASPNETCLASSIC : base(next) #endif { #if !ASPNETCLASSIC Next = next; #endif Executor = queryExecutor ?? throw new ArgumentNullException(nameof(queryExecutor)); _resultSerializer = resultSerializer ?? throw new ArgumentNullException(nameof(resultSerializer)); Options = options ?? throw new ArgumentNullException(nameof(options)); if (Options.Path.Value.Length > 1) { var path1 = new PathString(options.Path.Value.TrimEnd('/')); PathString path2 = path1.Add(new PathString("/")); _isPathValid = ctx => ctx.IsValidPath(path1, path2); } else { _isPathValid = ctx => ctx.IsValidPath(options.Path); } }
protected QueryMiddlewareBase( RequestDelegate next, IPathOptionAccessor options, IQueryResultSerializer serializer, IErrorHandler errorHandler) { if (options == null) { throw new ArgumentNullException(nameof(options)); } _serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); ErrorHandler = errorHandler ?? throw new ArgumentNullException(nameof(serializer)); Next = next; if (options.Path.Value.Length > 1) { var path1 = new PathString(options.Path.Value.TrimEnd('/')); PathString path2 = path1.Add(new PathString("/")); _isPathValid = ctx => ctx.IsValidPath(path1, path2); } else { _isPathValid = ctx => ctx.IsValidPath(options.Path); } }
/// <summary> /// Gets WebSub WebHook URL. /// </summary> /// <param name="request">The request.</param> /// <param name="subscriptionId">The subscription identifier.</param> /// <returns></returns> public static string GetWebSubWebHookUrl(this HttpRequest request, string subscriptionId) { PathString hostPathString = new PathString("//" + request.Host); PathString webHookPathString = new PathString("/api/webhooks/incoming/websub/"); return(request.Scheme + ":" + hostPathString.Add(request.PathBase).Add(webHookPathString).Value + subscriptionId); }
public static async Task HandleApiRequestAsync(PathString rootApiPath, HttpRequest request, HttpResponse response, IHostingEnvironment env) { PathString apiPath = rootApiPath.Add(new PathString("list")); Action <string, HttpRequest, HttpResponse, IHostingEnvironment> handlerFunc; if (request.Path.StartsWithSegments(apiPath)) { handlerFunc = HandleListApi; } else if (request.Path.StartsWithSegments((apiPath = rootApiPath.Add(new PathString("item"))))) { handlerFunc = HandleGetItemApi; } else if (request.Path.StartsWithSegments((apiPath = rootApiPath.Add(new PathString("update"))))) { handlerFunc = HandleUpdateItemApi; } else if (request.Path.StartsWithSegments((apiPath = rootApiPath.Add(new PathString("delete"))))) { handlerFunc = HandleDeleteItemApi; } else { apiPath = rootApiPath; handlerFunc = Handle404Api; } await Task.Factory.StartNew(async() => { try { handlerFunc((request.Path.Value.Length > apiPath.Value.Length) ? request.Path.Value.Substring(apiPath.Value.Length) : "", request, response, env); } catch (Exception exc) { if (response.HasStarted) { response.Clear(); } await SendErrorResponseAsync(response, "Unexpected Error", env, tw => { tw.WriteString("Unexpected error handling API request "); tw.WriteElementString("code", request.Path.Value); tw.WriteString("."); }, exc); } }); }
public static void UseSubAppModules(this IApplicationBuilder app, PathString modulePrefix = default) { app = app ?? throw new ArgumentNullException(); //app.Map(modulePrefix, subapp => //{ // subapp.UseRouting(); // subapp.UseEndpoints(b => // { // b.MapGet("/", async http => // { // await http.Response.WriteAsync(http.Request.PathBase); // }); // }); //}); //return; var moduleManager = app.ApplicationServices.GetRequiredService <IModuleManager>(); moduleManager.Initialize(); var pipelineCacheManager = app.ApplicationServices.GetRequiredService <IPipelineCacheManager>(); var modules = moduleManager.GetModules(); app.MapWhen(http => http.Request.Path.StartsWithSegments(modulePrefix), subapp => { foreach (var module in modules) { subapp.Map(modulePrefix.Add("/" + module.ModuleName), subapp2 => { var(requestDelegate, service, alc) = pipelineCacheManager.GetOrCache(module.ModuleName); if (requestDelegate != null) { subapp2.UseRouting(); subapp2.UseEndpoints(builder => builder.MapGet("/appinfo", async(http) => { if (http.Request.PathBase.StartsWithSegments(modulePrefix, out var prefixPath)) { var moduleName = prefixPath.ToString().Remove(0, 1); http.Response.ContentType = "application/json;charset=utf-8"; await http.Response.WriteAsync(JsonSerializer.Serialize(new { pathBase = http.Request.PathBase.ToUriComponent(), moduleName = moduleName })); } })); subapp2.Use(next => async http => { var http2 = new DefaultHttpContextFactory(service).Create(http.Features); using (alc.EnterContextualReflection()) { await requestDelegate(http2); } }); } }); }
public static PathString SafeAdd(this PathString path, string newSegmentString) { if (!newSegmentString.StartsWith("/")) { newSegmentString = $"/{newSegmentString}"; } return(path.Add(newSegmentString)); }
void AddFeaturesRecursively(IReadOnlyDictionary <Feature, FeatureDefinition> features, PathString prefix) { foreach (var feature in features) { if (_artifacts.TryGetValue(feature.Key, out var artifacts)) { AddArtifacts( prefix.Add($"/{feature.Value.Name}"), artifacts.Commands, artifacts.EventSources, artifacts.Events, artifacts.Queries, artifacts.ReadModels); } AddFeaturesRecursively(feature.Value.SubFeatures, prefix.Add($"/{feature.Value.Name}")); } }
private static string GenerateClientUrl(PathString applicationPath, string path) { if (path.StartsWith("~/", StringComparison.Ordinal)) { var segment = new PathString(path.Substring(1)); return applicationPath.Add(segment).Value; } return path; }
public async Task InvokeAsync(HttpContext httpContext) { if (httpContext.Request.Path.StartsWithSegments(basePath.Add(TriggerEndpointPaths.API_PATH))) { var schedulerFactory = (ISchedulerFactory)httpContext.RequestServices.GetService(typeof(ISchedulerFactory)); var jobName = httpContext.Request.Query["jobName"]; var isRedirect = httpContext.Request.Query["isRedirect"]; var scheduler = await schedulerFactory.GetScheduler(default);
private static string GenerateClientUrl(PathString applicationPath, string path) { if (path.StartsWith("~/", StringComparison.Ordinal)) { var segment = new PathString(path.Substring(1)); return(applicationPath.Add(segment).Value); } return(path); }
/// <summary> /// Adds analytics server to the Http pipeline of a web application. /// </summary> /// <param name="app">The Microsoft.AspNetCore.Builder.IApplicationBuilder instance that the analytics server will be added to.</param> /// <param name="basePath">Base path of the analytics server to capture incoming requests.</param> /// <returns>The Microsoft.AspNetCore.Builder.IApplicationBuilder so that additional calls can be chained.</returns> public static IApplicationBuilder UseAnalyticsServer(this IApplicationBuilder app, PathString basePath) { if (string.IsNullOrWhiteSpace(basePath)) { basePath = "/analytics"; } app.Map(basePath.Add("/track"), appBuilder => appBuilder.UseMiddleware <AnalyticsTrackingMiddleware>()); return(app); }
public void PathAndQueryStringAreCombinable( string pathValue, string queryValue, string combinedValue) { var path = new PathString(pathValue); var query = new QueryString(queryValue); path.Add(query).ShouldBe(combinedValue); (path + query).ShouldBe(combinedValue); }
public void AddPathString_HandlesLeadingAndTrailingSlashes(string appString, string concatString, string expected) { // Arrange var appPath = new PathString(appString); var concatPath = new PathString(concatString); // Act var result = appPath.Add(concatPath); // Assert Assert.Equal(expected, result.Value); }
public void AddPathString_HandlesNullAndEmptyStrings(string appString, string concatString) { // Arrange var appPath = new PathString(appString); var concatPath = new PathString(concatString); // Act var result = appPath.Add(concatPath); // Assert Assert.False(result.HasValue); }
public override async Task Invoke(IOwinContext context) { var workContext = _container.Resolve <WorkContext>(); var requestPath = context.Request.Path.Value; var normalizedPath = new PathString(); //add store to path normalizedPath = normalizedPath.Add(new PathString("/" + workContext.CurrentStore.Id)); //add language to path normalizedPath = normalizedPath.Add(new PathString("/" + workContext.CurrentLanguage.CultureName)); //add remaining path part without store and language requestPath = Regex.Replace(requestPath, "/" + workContext.CurrentStore.Id + "/", "/", RegexOptions.IgnoreCase); requestPath = Regex.Replace(requestPath, "/" + workContext.CurrentLanguage.CultureName + "/", "/", RegexOptions.IgnoreCase); normalizedPath = normalizedPath.Add(new PathString(requestPath)); //http://stackoverflow.com/questions/28252230/url-rewrite-in-owin-middleware System.Web.Routing.RequestContext requestContext = context.Environment["System.Web.Routing.RequestContext"] as System.Web.Routing.RequestContext; requestContext.HttpContext.RewritePath("~" + normalizedPath.Value); context.Request.Path = normalizedPath; await Next.Invoke(context); }
void AddArtifacts(PathString prefix, params IReadOnlyDictionary <ArtifactId, ArtifactDefinition>[] artifactsByTypes) { foreach (var artifactByType in artifactsByTypes) { foreach (var artifactDefinition in artifactByType) { var artifactType = artifactDefinition.Value.Type.GetActualType(); if (typeof(TArtifact).IsAssignableFrom(artifactType)) { _artifactPaths.Add(artifactType, prefix.Add($"/{artifactType.Name}")); } } } }
public static PathString AddStoreAndLangSegment(this PathString path, Store store, Language language) { if (store == null) { throw new ArgumentNullException(nameof(store)); } if (language == null) { throw new ArgumentNullException(nameof(language)); } var result = new PathString(); //add store to path result = result.Add(new PathString("/" + store.Id)); //add language to path result = result.Add(new PathString("/" + language.CultureName)); //need to remove store and language if it already exist in the path result = result.Add(new PathString(path.TrimStoreAndLangSegment(store, language))); return(result); }
/// <summary> /// Adds a remote BFF API endpoint /// </summary> /// <param name="endpoints"></param> /// <param name="localPath"></param> /// <param name="apiAddress"></param> /// <param name="requireAntiForgeryCheck"></param> /// <returns></returns> public static IEndpointConventionBuilder MapRemoteBffApiEndpoint( this IEndpointRouteBuilder endpoints, PathString localPath, string apiAddress, bool requireAntiForgeryCheck = true) { endpoints.CheckLicense(); return(endpoints.Map( localPath.Add("/{**catch-all}").Value, RemoteApiEndpoint.Map(localPath, apiAddress)) .WithMetadata(new BffRemoteApiEndpointMetadata { RequireAntiForgeryHeader = requireAntiForgeryCheck })); }
internal static string RebaseUrlCore(string value, string basePath, PathString virtualPathPrefix, PathString outputPath) { if (!UrlUtils.IsRelative(value)) { return(value); } value = UrlUtils.NormalizePath(virtualPathPrefix.Add(basePath).Add("/" + value), canonicalize: true); if (outputPath.HasValue) { value = UrlUtils.MakeRelativePath(outputPath, value); } return(value); }
/// <summary> /// Equally to IUrlHelper.Content /// </summary> /// <param name="relativePath"></param> /// <returns></returns> public static string Content(this LinkGenerator generator, string contentPath) { if (string.IsNullOrEmpty(contentPath)) { return(null); } else if (contentPath[0] == '~') { var segment = new PathString(contentPath.Substring(1)); var _httpContextAccessor = EngineContext.Current.Resolve <IHttpContextAccessor>(); var applicationPath = new PathString(""); //_httpContextAccessor.HttpContext.Request.PathBase; return(applicationPath.Add(segment).Value); } return(contentPath); }
string RebaseUrl(string basePath, PathString pathPrefix, string value) { var quote = RemoveQuotes(ref value); if (quote == null || value.StartsWith('/') || value.StartsWith("data:", StringComparison.OrdinalIgnoreCase) || !Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out Uri uri) || uri.IsAbsoluteUri) { return(value); } var url = pathPrefix.Add(basePath + value); return(string.Concat(quote, url, quote)); }
public static void UseSubAppModules(this IApplicationBuilder app, PathString modulePrefix = default) { app = app ?? throw new ArgumentNullException(); //app.Map(modulePrefix, subapp => //{ // subapp.UseRouting(); // subapp.UseEndpoints(b => // { // b.MapGet("/", async http => // { // await http.Response.WriteAsync(http.Request.PathBase); // }); // }); //}); //return; var moduleManager = app.ApplicationServices.GetRequiredService <IModuleManager>(); var modules = moduleManager.GetModules(); foreach (var module in modules) { var path = modulePrefix.Add("/" + module.ModuleName); app.Map(path, subapp => { var option = new SubAppOptions { SubAppPrefix = modulePrefix, ModuleManifest = module, }; var manager = subapp.ApplicationServices.GetRequiredService <IModuleManager>(); var logger = subapp.ApplicationServices.GetRequiredService <ILogger <SubAppMiddleware> >(); subapp.UseMiddleware <SubAppMiddleware>(option, manager, logger); subapp.UseRouting(); subapp.UseEndpoints(builder => builder.MapGet("/appinfo", async(http) => { http.Response.ContentType = "application/json;charset=utf-8"; await http.Response.WriteAsync(JsonSerializer.Serialize(new { pathBase = http.Request.PathBase, moduleName = module.ModuleName })); })); }); } }
public PathString Resolve(VirtualPathContext virtualPathContext, RequestCulture defaultRequestCulture, RequestCulture requestCulture) { // Handle when the page is added as a route parameter object value; if (virtualPathContext.Values.TryGetValue("page", out value)) { var page = value as Page; if (page == null) return null; object culture; if (virtualPathContext.Values.TryGetValue("culture", out culture)) { string cultureValue = culture as string; if (cultureValue != null) { requestCulture = new RequestCulture(cultureValue); } } var trie = _routeResolverTrie.LoadTrieAsync(requestCulture); trie.Wait(); var node = trie.Result.FirstOrDefault(n => n.Value.PageId == page.Id); PathString path = new PathString(); if (defaultRequestCulture.Culture.Name != requestCulture.Culture.Name) { path = path.Add("/" + requestCulture.Culture.TwoLetterISOLanguageName); } return path.Add(node.Key); } if (virtualPathContext.Values.TryGetValue("id", out value)) { var id = value as string; if (id == null) return null; object culture; if (virtualPathContext.Values.TryGetValue("culture", out culture)) { string cultureValue = culture as string; if (cultureValue != null) { requestCulture = new RequestCulture(cultureValue); } } var trie = _routeResolverTrie.LoadTrieAsync(requestCulture); trie.Wait(); var node = trie.Result.FirstOrDefault(n => n.Value.PageId == id); PathString path = new PathString(); if (defaultRequestCulture.Culture.Name != requestCulture.Culture.Name) { path = path.Add("/" + requestCulture.Culture.TwoLetterISOLanguageName); } return path.Add(node.Key); } return null; }