public async Task ExecuteResultAsync_InvokesForbiddenAsyncOnAllConfiguredSchemes() { // Arrange var authProperties = new AuthenticationProperties(); var authenticationManager = new Mock<AuthenticationManager>(); authenticationManager .Setup(c => c.ForbidAsync("Scheme1", authProperties)) .Returns(TaskCache.CompletedTask) .Verifiable(); authenticationManager .Setup(c => c.ForbidAsync("Scheme2", authProperties)) .Returns(TaskCache.CompletedTask) .Verifiable(); var httpContext = new Mock<HttpContext>(); httpContext.Setup(c => c.RequestServices).Returns(CreateServices()); httpContext.Setup(c => c.Authentication).Returns(authenticationManager.Object); var result = new ForbidResult(new[] { "Scheme1", "Scheme2" }, authProperties); var routeData = new RouteData(); var actionContext = new ActionContext( httpContext.Object, routeData, new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert authenticationManager.Verify(); }
/// <summary> /// Creates a new <see cref="ActionContext"/>. /// </summary> /// <param name="httpContext">The <see cref="Http.HttpContext"/> for the current request.</param> /// <param name="routeData">The <see cref="AspNet.Routing.RouteData"/> for the current request.</param> /// <param name="actionDescriptor">The <see cref="Abstractions.ActionDescriptor"/> for the selected action.</param> /// <param name="modelState">The <see cref="ModelStateDictionary"/>.</param> public ActionContext( HttpContext httpContext, RouteData routeData, ActionDescriptor actionDescriptor, ModelStateDictionary modelState) { if (httpContext == null) { throw new ArgumentNullException(nameof(httpContext)); } if (routeData == null) { throw new ArgumentNullException(nameof(routeData)); } if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } if (modelState == null) { throw new ArgumentNullException(nameof(modelState)); } HttpContext = httpContext; RouteData = routeData; ActionDescriptor = actionDescriptor; ModelState = modelState; }
public async virtual Task RouteAsync(RouteContext context) { for (var i = 0; i < Count; i++) { var route = this[i]; var oldRouteData = context.RouteData; var newRouteData = new RouteData(oldRouteData); newRouteData.Routers.Add(route); try { context.RouteData = newRouteData; await route.RouteAsync(context); if (context.IsHandled) { break; } } finally { if (!context.IsHandled) { context.RouteData = oldRouteData; } } } }
public async Task RouteAsync(RouteContext context) { EnsureLoggers(context.HttpContext); using(_logger.BeginScope("SubdomainTemplateRoute.RouteAsync")) { var host = context.HttpContext.Request.Host.Value; if(host.Contains(":")) { host = host.Substring(0, host.IndexOf(":")); } var values = _matcher.Match(host); if(values == null) { _logger.Log(x => x.Verbose, x => x.LogVerbose(nameof(SubdomainTemplateRoute) + " " + Name + " - Host \"" + context.HttpContext.Request.Host + "\" did not match.")); return; } var oldRouteData = context.RouteData; var newRouteData = new RouteData(oldRouteData); newRouteData.DataTokens.MergeValues(DataTokens); newRouteData.Routers.Add(_target); newRouteData.Values.MergeValues(values); try { context.RouteData = newRouteData; await _innerRoute.RouteAsync(context); } finally { if(!context.IsHandled) { context.RouteData = oldRouteData; } } } }
public async Task RouteAsync(RouteContext context) { // Saving and restoring the original route data ensures that any values we // add won't 'leak' if action selection doesn't match. var oldRouteData = context.RouteData; // For diagnostics and link-generation purposes, routing should include // a list of IRoute instances that lead to the ultimate destination. // It's the responsibility of each IRouter to add the 'next' before // calling it. var newRouteData = new RouteData(oldRouteData); newRouteData.Routers.Add(_next); var locale = GetLocale(context.HttpContext) ?? "en-US"; newRouteData.Values.Add("locale", locale); try { context.RouteData = newRouteData; await _next.RouteAsync(context); } finally { if (!context.IsHandled) { context.RouteData = oldRouteData; } } }
/// <summary> /// Updates the request when there is no template to render the content. /// </summary> internal async Task UpdateOnMissingTemplateAsync(RouteData routeData) { var __readonly = _readonly; _readonly = false; await _engine.UpdateRequestOnMissingTemplateAsync(routeData); _readonly = __readonly; }
/// <summary> /// Creates a new <see cref="ActionContext"/>. /// </summary> /// <param name="httpContext">The <see cref="Http.HttpContext"/> for the current request.</param> /// <param name="routeData">The <see cref="AspNet.Routing.RouteData"/> for the current request.</param> /// <param name="actionDescriptor">The <see cref="Abstractions.ActionDescriptor"/> for the selected action.</param> public ActionContext( HttpContext httpContext, RouteData routeData, ActionDescriptor actionDescriptor) : this(httpContext, routeData, actionDescriptor, new ModelStateDictionary()) { }
public ControllerRunner(string controller, string action, HttpContext httpContext, RouteData routeData) { _controller = controller; _action = action; _httpContext = httpContext; _routeData = routeData; }
public RenderPlaceholderArgs(HttpContext httpContext, RouteData routeData, Item item, string name, TextWriter output) { HttpContext = httpContext; RouteData = routeData; Item = item; Name = name; Output = output; }
public RenderRenderingArgs(HttpContext httpContext, RouteData routeData, Item item, Rendering rendering, TextWriter output) { HttpContext = httpContext; RouteData = routeData; Item = item; Rendering = rendering; Output = output; }
private static ActionContext GetActionContext(HttpContext httpContext) { var routeData = new RouteData(); routeData.Routers.Add(Mock.Of<IRouter>()); return new ActionContext(httpContext, routeData, new ActionDescriptor()); }
/// <summary> /// Gets the route information /// </summary> /// <param name="routeData">Raw route data from ASP.NET MVC</param> /// <returns>Processed route information</returns> public IEnumerable<RouteInfo> GetRoutes(RouteData routeData) { return _actionDescriptorsCollectionProvider.ActionDescriptors.Items .OfType<ControllerActionDescriptor>() .Where(a => a.AttributeRouteInfo?.Template != null) .Select(ProcessAttributeRoute) // Sort by Order then Precedence, same as InnerAttributeRoute .OrderBy(x => x.Order) .ThenBy(x => x.Precedence) .ThenBy(x => x.Url, StringComparer.Ordinal); }
public void OnBeforeAction(ActionDescriptor actionDescriptor, HttpContext httpContext, RouteData routeData) { string name = this.GetNameFromRouteContext(routeData); var telemetry = httpContext.RequestServices.GetService<RequestTelemetry>(); if (!string.IsNullOrEmpty(name) && telemetry != null && telemetry is RequestTelemetry) { name = httpContext.Request.Method + " " + name; ((RequestTelemetry)telemetry).Name = name; } }
public async Task RouteAsync([NotNull] RouteContext context) { var services = context.HttpContext.RequestServices; // Verify if AddMvc was done before calling UseMvc // We use the MvcMarkerService to make sure if all the services were added. MvcServicesHelper.ThrowIfMvcNotRegistered(services); EnsureLogger(context.HttpContext); using (_logger.BeginScope("MvcRouteHandler.RouteAsync")) { var actionSelector = services.GetRequiredService<IActionSelector>(); var actionDescriptor = await actionSelector.SelectAsync(context); if (actionDescriptor == null) { LogActionSelection(actionSelected: false, actionInvoked: false, handled: context.IsHandled); return; } // Replacing the route data allows any code running here to dirty the route values or data-tokens // without affecting something upstream. var oldRouteData = context.RouteData; var newRouteData = new RouteData(oldRouteData); if (actionDescriptor.RouteValueDefaults != null) { foreach (var kvp in actionDescriptor.RouteValueDefaults) { if (!newRouteData.Values.ContainsKey(kvp.Key)) { newRouteData.Values.Add(kvp.Key, kvp.Value); } } } try { context.RouteData = newRouteData; await InvokeActionAsync(context, actionDescriptor); context.IsHandled = true; } finally { if (!context.IsHandled) { context.RouteData = oldRouteData; } } LogActionSelection(actionSelected: true, actionInvoked: true, handled: context.IsHandled); } }
/// <summary> /// Gets the route information /// </summary> /// <param name="routeData">Raw route data from ASP.NET MVC</param> /// <returns>Processed route information</returns> public IEnumerable<RouteInfo> GetRoutes(RouteData routeData) { var routeCollection = routeData.Routers.OfType<RouteCollection>().First(); for (var i = 0; i < routeCollection.Count; i++) { var route = routeCollection[i]; if (route is TemplateRoute) { yield return ProcessTemplateRoute((TemplateRoute)route); } } }
/// <summary> /// Prepares the request. /// </summary> /// <returns> /// Returns false if the request was not successfully prepared /// </returns> public async Task<bool> PrepareRequestAsync(RouteData routeData) { // note - at that point the original legacy module did something do handle IIS custom 404 errors // ie pages looking like /anything.aspx?404;/path/to/document - I guess the reason was to support // "directory urls" without having to do wildcard mapping to ASP.NET on old IIS. This is a pain // to maintain and probably not used anymore - removed as of 06/2012. @zpqrtbnk. // // to trigger Umbraco's not-found, one should configure IIS and/or ASP.NET custom 404 errors // so that they point to a non-existing page eg /redirect-404.aspx // TODO: SD: We need more information on this for when we release 4.10.0 as I'm not sure what this means. //find domain //FindDomain(); // if request has been flagged to redirect then return // whoever called us is in charge of actually redirecting if (_pcr.IsRedirect) { return false; } // set the culture on the thread - once, so it's set when running document lookups Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = _pcr.Culture; //find the published content if it's not assigned. This could be manually assigned with a custom route handler, or // with something like EnsurePublishedContentRequestAttribute or UmbracoVirtualNodeRouteHandler. Those in turn call this method // to setup the rest of the pipeline but we don't want to run the finders since there's one assigned. if (_pcr.PublishedContent == null) { // find the document & template await FindPublishedContentAndTemplateAsync(routeData); } // handle wildcard domains //HandleWildcardDomains(); // set the culture on the thread -- again, 'cos it might have changed due to a finder or wildcard domain Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = _pcr.Culture; // trigger the Prepared event - at that point it is still possible to change about anything // even though the request might be flagged for redirection - we'll redirect _after_ the event // // also, OnPrepared() will make the PublishedContentRequest readonly, so nothing can change // _pcr.OnPrepared(); // we don't take care of anything so if the content has changed, it's up to the user // to find out the appropriate template //complete the PCR and assign the remaining values return ConfigureRequest(); }
public static void AfterAction( this DiagnosticSource diagnosticSource, ActionDescriptor actionDescriptor, HttpContext httpContext, RouteData routeData) { if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.AfterAction")) { diagnosticSource.Write( "Microsoft.AspNet.Mvc.AfterAction", new { actionDescriptor, httpContext = httpContext, routeData = routeData }); } }
public void EmptyResult_ExecuteResult_IsANoOp() { // Arrange var emptyResult = new EmptyResult(); var httpContext = new Mock<HttpContext>(MockBehavior.Strict); var routeData = new RouteData(); var actionDescriptor = new ActionDescriptor(); var context = new ActionContext(httpContext.Object, routeData, actionDescriptor); // Act & Assert (does not throw) emptyResult.ExecuteResult(context); }
private string GetNameFromRouteContext(RouteData routeData) { string name = null; if (routeData.Values.Count > 0) { var routeValues = routeData.Values; object controller; routeValues.TryGetValue("controller", out controller); string controllerString = (controller == null) ? string.Empty : controller.ToString(); if (!string.IsNullOrEmpty(controllerString)) { name = controllerString; object action; routeValues.TryGetValue("action", out action); string actionString = (action == null) ? string.Empty : action.ToString(); if (!string.IsNullOrEmpty(actionString)) { name += "/" + actionString; } if (routeValues.Keys.Count > 2) { // Add parameters var sortedKeys = routeValues.Keys .Where(key => !string.Equals(key, "controller", StringComparison.OrdinalIgnoreCase) && !string.Equals(key, "action", StringComparison.OrdinalIgnoreCase) && !string.Equals(key, AttributeRouting.RouteGroupKey, StringComparison.OrdinalIgnoreCase)) .OrderBy(key => key, StringComparer.OrdinalIgnoreCase) .ToArray(); if (sortedKeys.Length > 0) { string arguments = string.Join(@"/", sortedKeys); name += " [" + arguments + "]"; } } } } return name; }
internal async Task<bool> RouteUmbracoContentAsync(UmbracoContext umbCtx, PublishedContentRequest pcr, RouteData routeData) { //Initialize the context, this will be called a few times but the initialize logic // only executes once. There might be a nicer way to do this but the RouteContext and // other request scoped instances are not available yet. umbCtx.Initialize(pcr); //Prepare the request if it hasn't already been done if (pcr.IsPrepared == false) { if (await pcr.PrepareAsync(routeData)) { if (umbCtx.HasContent == false) return false; } } return umbCtx.HasContent; }
public void HttpStatusCodeResult_ExecuteResultSetsResponseStatusCode() { // Arrange var result = new HttpStatusCodeResult(StatusCodes.Status404NotFound); var httpContext = new DefaultHttpContext(); var routeData = new RouteData(); var actionDescriptor = new ActionDescriptor(); var context = new ActionContext(httpContext, routeData, actionDescriptor); // Act result.ExecuteResult(context); // Assert Assert.Equal(StatusCodes.Status404NotFound, httpContext.Response.StatusCode); }
public async Task RouteAsync(RouteContext context) { // Saving and restoring the original route data ensures that any values we // add won't 'leak' if action selection doesn't match. var oldRouteData = context.RouteData; // For diagnostics and link-generation purposes, routing should include // a list of IRoute instances that lead to the ultimate destination. // It's the responsibility of each IRouter to add the 'next' before // calling it. var newRouteData = new RouteData(oldRouteData); newRouteData.Routers.Add(_next); //It's an umbraco route, need to find out if it matches any content if (newRouteData.Values.ContainsKey("_umbracoRoute") //exit quickly if there's any file extension && newRouteData.Values["_umbracoRoute"].ToString().Contains(".") == false) { var umbCtx = context.HttpContext.RequestServices.GetRequiredService<UmbracoContext>(); var umbControllerTypes = context.HttpContext.ApplicationServices.GetRequiredService<UmbracoControllerTypeCollection>(); var pcr = context.HttpContext.RequestServices.GetRequiredService<PublishedContentRequest>(); if (await RouteUmbracoContentAsync(umbCtx, pcr, newRouteData)) { var routeDef = GetUmbracoRouteValues(umbCtx, umbControllerTypes); newRouteData.DataTokens["umbraco-route-def"] = routeDef; var surfaceFormHelper = context.HttpContext.ApplicationServices.GetRequiredService<SurfaceFormHelper>(); var formInfo = surfaceFormHelper.GetFormInfo(context); if (formInfo != null) { //there is form data, route to the surface controller SetUmbracoRouteValues(formInfo, newRouteData); } else { //there is no form data, route normally SetUmbracoRouteValues(routeDef, newRouteData); } } } await ExecuteNext(context, newRouteData, oldRouteData); }
public async virtual Task RouteAsync(RouteContext context) { EnsureLogger(context.HttpContext); using (_logger.BeginScope("RouteCollection.RouteAsync")) { for (var i = 0; i < Count; i++) { var route = this[i]; var oldRouteData = context.RouteData; var newRouteData = new RouteData(oldRouteData); newRouteData.Routers.Add(route); try { context.RouteData = newRouteData; await route.RouteAsync(context); if (context.IsHandled) { break; } } finally { if (!context.IsHandled) { context.RouteData = oldRouteData; } } } if (_logger.IsEnabled(LogLevel.Verbose)) { _logger.WriteValues(new RouteCollectionRouteAsyncValues() { Handled = context.IsHandled, Routes = _routes }); } } }
/// <summary> /// Creates a new <see cref="RouteData"/> instance with values copied from <paramref name="other"/>. /// </summary> /// <param name="other">The other <see cref="RouteData"/> instance to copy.</param> public RouteData(RouteData other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } Routers = new List<IRouter>(other.Routers); // Perf: Avoid allocating DataTokens and RouteValues unless we need to make a copy. if (other._dataTokens != null) { _dataTokens = new RouteValueDictionary(other._dataTokens); } if (other._values != null) { _values = new RouteValueDictionary(other._values); } }
public void FormatFilter_ContextContainsFormat_InRouteAndQueryData() { // If the format is present in both route and query data, the one in route data wins // Arrange var mediaType = MediaTypeHeaderValue.Parse("application/json"); var mockObjects = new MockObjects("json", FormatSource.RouteData); var httpContext = new Mock<HttpContext>(); httpContext.Setup(c => c.Response).Returns(new Mock<HttpResponse>().Object); // Query contains xml httpContext.Setup(c => c.Request.Query.ContainsKey("format")).Returns(true); httpContext.Setup(c => c.Request.Query["format"]).Returns("xml"); // Routedata contains json var data = new RouteData(); data.Values.Add("format", "json"); var ac = new ActionContext(httpContext.Object, data, new ActionDescriptor()); var resultExecutingContext = new ResultExecutingContext( ac, new IFilterMetadata[] { }, new ObjectResult("Hello!"), controller: new object()); var resourceExecutingContext = new ResourceExecutingContext( ac, new IFilterMetadata[] { }); var filter = new FormatFilter(mockObjects.OptionsManager); // Act filter.OnResourceExecuting(resourceExecutingContext); filter.OnResultExecuting(resultExecutingContext); // Assert var objectResult = Assert.IsType<ObjectResult>(resultExecutingContext.Result); Assert.Equal(1, objectResult.ContentTypes.Count); AssertMediaTypesEqual(mediaType, objectResult.ContentTypes[0]); }
public void ChallengeResult_Execute() { // Arrange var result = new ChallengeResult(new string[] { }, null); var httpContext = new Mock<HttpContext>(); var httpResponse = new Mock<HttpResponse>(); httpContext.Setup(o => o.Response).Returns(httpResponse.Object); var routeData = new RouteData(); routeData.Routers.Add(Mock.Of<IRouter>()); var actionContext = new ActionContext(httpContext.Object, routeData, new ActionDescriptor()); // Act result.ExecuteResult(actionContext); // Assert httpResponse.Verify(c => c.Challenge(null, (IEnumerable<string>)new string[] { }), Times.Exactly(1)); }
public async Task ChallengeResult_ExecuteNoSchemes() { // Arrange var result = new ChallengeResult(new string[] { }, null); var httpContext = new Mock<HttpContext>(); var auth = new Mock<AuthenticationManager>(); httpContext.Setup(o => o.Authentication).Returns(auth.Object); var routeData = new RouteData(); routeData.Routers.Add(Mock.Of<IRouter>()); var actionContext = new ActionContext(httpContext.Object, routeData, new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert auth.Verify(c => c.ChallengeAsync((AuthenticationProperties)null), Times.Exactly(1)); }
public void ChallengeResult_Execute() { // Arrange var result = new ChallengeResult("", null); var httpContext = new Mock<HttpContext>(); var auth = new Mock<AuthenticationManager>(); httpContext.Setup(o => o.Authentication).Returns(auth.Object); var routeData = new RouteData(); routeData.Routers.Add(Mock.Of<IRouter>()); var actionContext = new ActionContext(httpContext.Object, routeData, new ActionDescriptor()); // Act result.ExecuteResult(actionContext); // Assert auth.Verify(c => c.Challenge("", null), Times.Exactly(1)); }
public void Initialize(RouteData routeData) { if (routeData?.Values == null) return; if (routeData.Values.ContainsKey("_umbracoRoute") == false) return; if (Initialized) return; _routeData = routeData; RequestPath = _httpContextAccessor.HttpContext.Request.Path; //This would be like looking up content in Umbraco var path = routeData.Values["_umbracoRoute"] + ".txt"; var filePath = Path.Combine(_appEnv.ApplicationBasePath, "UmbracoContent", path); if (File.Exists(filePath)) { using (var file = File.OpenText(filePath)) { var serializer = new JsonSerializer { ContractResolver = new CamelCasePropertyNamesContractResolver() }; Content = (PublishedContent)serializer.Deserialize(file, typeof(PublishedContent)); } } //TODO: This name/etc. is temporary from old testing AltTemplate = _httpContextAccessor.HttpContext.Request.Query["altTemplate"]; if (string.IsNullOrEmpty(AltTemplate)) { AltTemplate = "Umbraco"; } Initialized = true; }
public async Task ChallengeResult_Execute() { // Arrange var result = new ChallengeResult("", null); var httpContext = new Mock<HttpContext>(); httpContext.SetupGet(c => c.RequestServices).Returns(CreateServices().BuildServiceProvider()); var auth = new Mock<AuthenticationManager>(); httpContext.Setup(o => o.Authentication).Returns(auth.Object); var routeData = new RouteData(); routeData.Routers.Add(Mock.Of<IRouter>()); var actionContext = new ActionContext(httpContext.Object, routeData, new ActionDescriptor()); // Act await result.ExecuteResultAsync(actionContext); // Assert auth.Verify(c => c.ChallengeAsync("", null), Times.Exactly(1)); }
/// <summary> /// Creates a new <see cref="RouteData"/> instance with values copied from <paramref name="other"/>. /// </summary> /// <param name="other">The other <see cref="RouteData"/> instance to copy.</param> public RouteData([NotNull] RouteData other) { DataTokens = new Dictionary <string, object>(other.DataTokens, StringComparer.OrdinalIgnoreCase); Routers = new List <IRouter>(other.Routers); Values = new RouteValueDictionary(other.Values); }