/// <summary> /// Improve SEO by stopping duplicate URL's due to case differences or trailing slashes. /// See http://googlewebmastercentral.blogspot.co.uk/2010/04/to-slash-or-not-to-slash.html /// </summary> /// <param name="routeOptions">The routing options.</param> private static void ConfigureRouting(RouteOptions routeOptions) { // TODO: AppendTrailingSlash does not yet exist but will be added in the next version of MVC. // All generated URL's should append a trailing slash. // routeOptions.AppendTrailingSlash = true; // All generated URL's should be lower-case. routeOptions.LowercaseUrls = true; // TODO: IgnoreRoute does not yet exist in MVC 6. // // IgnoreRoute - Tell the routing system to ignore certain routes for better performance. // // Ignore .axd files. // routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // // Ignore everything in the Content folder. // routes.IgnoreRoute("Content/{*pathInfo}"); // // Ignore everything in the Scripts folder. // routes.IgnoreRoute("Scripts/{*pathInfo}"); // // Ignore the Forbidden.html file. // routes.IgnoreRoute("Error/Forbidden.html"); // // Ignore the GatewayTimeout.html file. // routes.IgnoreRoute("Error/GatewayTimeout.html"); // // Ignore the ServiceUnavailable.html file. // routes.IgnoreRoute("Error/ServiceUnavailable.html"); // // Ignore the humans.txt file. // routes.IgnoreRoute("humans.txt"); }
public void GetVirtualPath_NoBestEffort_NoMatch() { // Arrange var route1 = CreateRoute(accept: false, match: true, matchValue: "best"); var route2 = CreateRoute(accept: false, match: true, matchValue: "bad"); var route3 = CreateRoute(accept: false, match: true, matchValue: "bad"); var routeCollection = new RouteCollection(); routeCollection.Add(route1.Object); routeCollection.Add(route2.Object); routeCollection.Add(route3.Object); var options = new RouteOptions() { UseBestEffortLinkGeneration = false, }; var virtualPathContext = CreateVirtualPathContext(options: options); // Act var path = routeCollection.GetVirtualPath(virtualPathContext); Assert.Null(path); // All of these should be called route1.Verify(r => r.GetVirtualPath(It.IsAny <VirtualPathContext>()), Times.Once()); route2.Verify(r => r.GetVirtualPath(It.IsAny <VirtualPathContext>()), Times.Once()); route3.Verify(r => r.GetVirtualPath(It.IsAny <VirtualPathContext>()), Times.Once()); }
public void GetVirtualPath_BestEffort_FirstValidatedValuesWins_ShortCircuit() { // Arrange var route1 = CreateRoute(accept: false, match: true, matchValue: "bad"); var route2 = CreateRoute(accept: true, match: true, matchValue: "best"); var route3 = CreateRoute(accept: true, match: true, matchValue: "bad"); var routeCollection = new RouteCollection(); routeCollection.Add(route1.Object); routeCollection.Add(route2.Object); routeCollection.Add(route3.Object); var options = new RouteOptions() { UseBestEffortLinkGeneration = true, }; var virtualPathContext = CreateVirtualPathContext(options: options); // Act var pathData = routeCollection.GetVirtualPath(virtualPathContext); Assert.Equal(new PathString("/best"), pathData.VirtualPath); Assert.Same(route2.Object, pathData.Router); Assert.Empty(pathData.DataTokens); route1.Verify(r => r.GetVirtualPath(It.IsAny <VirtualPathContext>()), Times.Once()); route2.Verify(r => r.GetVirtualPath(It.IsAny <VirtualPathContext>()), Times.Once()); route3.Verify(r => r.GetVirtualPath(It.IsAny <VirtualPathContext>()), Times.Never()); }
public void GetVirtualPath_NamedRoute_BestEffort_FirstRouteWins() { // Arrange var bestMatch = CreateNamedRoute("Match", accept: false, matchValue: "best"); var noMatch = CreateNamedRoute("NoMatch", accept: false, matchValue: "bad"); var routeCollection = new RouteCollection(); routeCollection.Add(noMatch); var innerRouteCollection = new RouteCollection(); innerRouteCollection.Add(bestMatch); routeCollection.Add(innerRouteCollection); var options = new RouteOptions() { UseBestEffortLinkGeneration = true, }; var virtualPathContext = CreateVirtualPathContext("Match", options: options); // Act var pathData = routeCollection.GetVirtualPath(virtualPathContext); Assert.Equal(new PathString("/best"), pathData.VirtualPath); var namedRouter = Assert.IsAssignableFrom <INamedRouter>(pathData.Router); Assert.Equal("Match", namedRouter.Name); Assert.Empty(pathData.DataTokens); }
public void GetVirtualPath_AmbiguousRoutes_RequiresRouteValueValidation_Error() { // Arrange var namedRoute = CreateNamedRoute("Ambiguous", accept: false); var routeCollection = new RouteCollection(); routeCollection.Add(namedRoute); var innerRouteCollection = new RouteCollection(); innerRouteCollection.Add(namedRoute); routeCollection.Add(innerRouteCollection); var options = new RouteOptions() { UseBestEffortLinkGeneration = true, }; var virtualPathContext = CreateVirtualPathContext("Ambiguous", options: options); // Act & Assert var ex = Assert.Throws <InvalidOperationException>(() => routeCollection.GetVirtualPath(virtualPathContext)); Assert.Equal("The supplied route name 'Ambiguous' is ambiguous and matched more than one route.", ex.Message); }
private void EnsureOptions(HttpContext context) { if (_options == null) { _options = context.RequestServices.GetRequiredService <IOptions <RouteOptions> >().Value; } }
private static RouteContext CreateRouteContext( string requestPath, ILoggerFactory loggerFactory = null, RouteOptions options = null) { if (loggerFactory == null) { loggerFactory = NullLoggerFactory.Instance; } if (options == null) { options = new RouteOptions(); } var request = new Mock <HttpRequest>(MockBehavior.Strict); request.SetupGet(r => r.Path).Returns(new PathString(requestPath)); var optionsAccessor = new Mock <IOptions <RouteOptions> >(MockBehavior.Strict); optionsAccessor.SetupGet(o => o.Value).Returns(options); var context = new Mock <HttpContext>(MockBehavior.Strict); context.Setup(m => m.RequestServices.GetService(typeof(ILoggerFactory))) .Returns(loggerFactory); context.Setup(m => m.RequestServices.GetService(typeof(IOptions <RouteOptions>))) .Returns(optionsAccessor.Object); context.SetupGet(c => c.Request).Returns(request.Object); return(new RouteContext(context.Object)); }
private static VirtualPathContext CreateVirtualPathContext( string routeName = null, ILoggerFactory loggerFactory = null, RouteOptions options = null) { if (loggerFactory == null) { loggerFactory = NullLoggerFactory.Instance; } if (options == null) { options = new RouteOptions(); } var request = new Mock <HttpRequest>(MockBehavior.Strict); var optionsAccessor = new Mock <IOptions <RouteOptions> >(MockBehavior.Strict); optionsAccessor.SetupGet(o => o.Options).Returns(options); var context = new Mock <HttpContext>(MockBehavior.Strict); context.Setup(m => m.RequestServices.GetService(typeof(ILoggerFactory))) .Returns(loggerFactory); context.Setup(m => m.RequestServices.GetService(typeof(IOptions <RouteOptions>))) .Returns(optionsAccessor.Object); context.SetupGet(c => c.Request).Returns(request.Object); return(new VirtualPathContext(context.Object, null, null, routeName)); }
/// <summary> /// Adds filters which help improve search engine optimization (SEO). /// </summary> private static void ConfigureSearchEngineOptimizationFilters(ICollection<IFilter> filters, RouteOptions routeOptions) { filters.Add(new RedirectToCanonicalUrlAttribute( appendTrailingSlash: true, // TODO: Add routeOptions.AppendTrailingSlash when it is added. lowercaseUrls: routeOptions.LowercaseUrls, ignoreControllers: new string[] { ControllerName.Elmah, ControllerName.Error })); }
private static RouteOptions GetRouteOptions( bool lowerCaseUrls = false, bool useBestEffortLinkGeneration = true, bool appendTrailingSlash = false) { var routeOptions = new RouteOptions(); routeOptions.LowercaseUrls = lowerCaseUrls; routeOptions.UseBestEffortLinkGeneration = useBestEffortLinkGeneration; routeOptions.AppendTrailingSlash = appendTrailingSlash; return(routeOptions); }
/// <summary> /// Improve SEO by stopping duplicate URL's due to case differences or trailing slashes. /// See http://googlewebmastercentral.blogspot.co.uk/2010/04/to-slash-or-not-to-slash.html /// </summary> /// <param name="routeOptions">The routing options.</param> private static void ConfigureRouting(RouteOptions routeOptions) { // All generated URL's should append a trailing slash. routeOptions.AppendTrailingSlash = true; // All generated URL's should be lower-case. routeOptions.LowercaseUrls = true; // TODO: IgnoreRoute does not yet exist in MVC 6. // // IgnoreRoute - Tell the routing system to ignore certain routes for better performance. // // Ignore .axd files. // routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // // Ignore everything in the Content folder. // routes.IgnoreRoute("Content/{*pathInfo}"); // // Ignore the humans.txt file. // routes.IgnoreRoute("humans.txt"); }
private static VirtualPathContext CreateVirtualPathContext( RouteValueDictionary values, RouteOptions options = null, string routeName = null) { var optionsAccessor = new Mock <IOptions <RouteOptions> >(MockBehavior.Strict); optionsAccessor.SetupGet(o => o.Value).Returns(options); var context = new Mock <HttpContext>(MockBehavior.Strict); context.Setup(m => m.RequestServices.GetService(typeof(IOptions <RouteOptions>))) .Returns(optionsAccessor.Object); context.Setup(m => m.RequestServices.GetService(typeof(ILoggerFactory))) .Returns(NullLoggerFactory.Instance); return(new VirtualPathContext( context.Object, ambientValues: null, values: values, routeName: routeName)); }
private static RouteContext CreateRouteContext( string requestPath, ILoggerFactory loggerFactory = null, RouteOptions options = null) { if (loggerFactory == null) { loggerFactory = NullLoggerFactory.Instance; } if (options == null) { options = new RouteOptions(); } var request = new Mock<HttpRequest>(MockBehavior.Strict); request.SetupGet(r => r.Path).Returns(new PathString(requestPath)); var optionsAccessor = new Mock<IOptions<RouteOptions>>(MockBehavior.Strict); optionsAccessor.SetupGet(o => o.Value).Returns(options); var context = new Mock<HttpContext>(MockBehavior.Strict); context.Setup(m => m.RequestServices.GetService(typeof(ILoggerFactory))) .Returns(loggerFactory); context.Setup(m => m.RequestServices.GetService(typeof(IOptions<RouteOptions>))) .Returns(optionsAccessor.Object); context.SetupGet(c => c.Request).Returns(request.Object); return new RouteContext(context.Object); }
private static VirtualPathContext CreateVirtualPathContext( RouteValueDictionary values, RouteOptions options = null, string routeName = null) { var optionsAccessor = new Mock<IOptions<RouteOptions>>(MockBehavior.Strict); optionsAccessor.SetupGet(o => o.Value).Returns(options); var context = new Mock<HttpContext>(MockBehavior.Strict); context.Setup(m => m.RequestServices.GetService(typeof(IOptions<RouteOptions>))) .Returns(optionsAccessor.Object); context.Setup(m => m.RequestServices.GetService(typeof(ILoggerFactory))) .Returns(NullLoggerFactory.Instance); return new VirtualPathContext( context.Object, ambientValues: null, values: values, routeName: routeName); }
public void GetVirtualPath_BestEffort_FirstValidatedValuesWins_Nested() { // Arrange var route1 = CreateRoute(accept: false, match: true, matchValue: "bad"); var route2 = CreateRoute(accept: false, match: true, matchValue: "bad"); var route3 = CreateRoute(accept: true, match: true, matchValue: "best"); var routeCollection = new RouteCollection(); routeCollection.Add(route1.Object); var innerRouteCollection = new RouteCollection(); innerRouteCollection.Add(route2.Object); innerRouteCollection.Add(route3.Object); routeCollection.Add(innerRouteCollection); var options = new RouteOptions() { UseBestEffortLinkGeneration = true, }; var virtualPathContext = CreateVirtualPathContext(options: options); // Act var pathData = routeCollection.GetVirtualPath(virtualPathContext); Assert.Equal(new PathString("/best"), pathData.VirtualPath); Assert.Same(route3.Object, pathData.Router); Assert.Empty(pathData.DataTokens); // All of these should be called route1.Verify(r => r.GetVirtualPath(It.IsAny<VirtualPathContext>()), Times.Once()); route2.Verify(r => r.GetVirtualPath(It.IsAny<VirtualPathContext>()), Times.Once()); route3.Verify(r => r.GetVirtualPath(It.IsAny<VirtualPathContext>()), Times.Once()); }
public void GetVirtualPath_NoBestEffort_NoMatch() { // Arrange var route1 = CreateRoute(accept: false, match: true, matchValue: "best"); var route2 = CreateRoute(accept: false, match: true, matchValue: "bad"); var route3 = CreateRoute(accept: false, match: true, matchValue: "bad"); var routeCollection = new RouteCollection(); routeCollection.Add(route1.Object); routeCollection.Add(route2.Object); routeCollection.Add(route3.Object); var options = new RouteOptions() { UseBestEffortLinkGeneration = false, }; var virtualPathContext = CreateVirtualPathContext(options: options); // Act var path = routeCollection.GetVirtualPath(virtualPathContext); Assert.Null(path); // All of these should be called route1.Verify(r => r.GetVirtualPath(It.IsAny<VirtualPathContext>()), Times.Once()); route2.Verify(r => r.GetVirtualPath(It.IsAny<VirtualPathContext>()), Times.Once()); route3.Verify(r => r.GetVirtualPath(It.IsAny<VirtualPathContext>()), Times.Once()); }
public void GetVirtualPath_NamedRoute_BestEffort_FirstRouteWins() { // Arrange var bestMatch = CreateNamedRoute("Match", accept: false, matchValue: "best"); var noMatch = CreateNamedRoute("NoMatch", accept: false, matchValue: "bad"); var routeCollection = new RouteCollection(); routeCollection.Add(noMatch); var innerRouteCollection = new RouteCollection(); innerRouteCollection.Add(bestMatch); routeCollection.Add(innerRouteCollection); var options = new RouteOptions() { UseBestEffortLinkGeneration = true, }; var virtualPathContext = CreateVirtualPathContext("Match", options: options); // Act var pathData = routeCollection.GetVirtualPath(virtualPathContext); Assert.Equal(new PathString("/best"), pathData.VirtualPath); var namedRouter = Assert.IsAssignableFrom<INamedRouter>(pathData.Router); Assert.Equal("Match", namedRouter.Name); Assert.Empty(pathData.DataTokens); }
public void GetVirtualPath_AmbiguousRoutes_RequiresRouteValueValidation_Error() { // Arrange var namedRoute = CreateNamedRoute("Ambiguous", accept: false); var routeCollection = new RouteCollection(); routeCollection.Add(namedRoute); var innerRouteCollection = new RouteCollection(); innerRouteCollection.Add(namedRoute); routeCollection.Add(innerRouteCollection); var options = new RouteOptions() { UseBestEffortLinkGeneration = true, }; var virtualPathContext = CreateVirtualPathContext("Ambiguous", options: options); // Act & Assert var ex = Assert.Throws<InvalidOperationException>(() => routeCollection.GetVirtualPath(virtualPathContext)); Assert.Equal("The supplied route name 'Ambiguous' is ambiguous and matched more than one route.", ex.Message); }
private static ServiceCollection GetServiceCollection() { var serviceCollection = new ServiceCollection(); serviceCollection.AddInstance<ILoggerFactory>(new NullLoggerFactory()); var routeOptions = new RouteOptions(); var accessor = new Mock<IOptions<RouteOptions>>(); accessor .SetupGet(options => options.Value) .Returns(routeOptions); serviceCollection.AddInstance<IOptions<RouteOptions>>(accessor.Object); serviceCollection.AddInstance<IInlineConstraintResolver>( new DefaultInlineConstraintResolver(accessor.Object)); return serviceCollection; }
private void EnsureOptions(HttpContext context) { if (_options == null) { _options = context.RequestServices.GetRequiredService<IOptions<RouteOptions>>().Value; } }
private static RouteOptions GetRouteOptions( bool lowerCaseUrls = false, bool useBestEffortLinkGeneration = true, bool appendTrailingSlash = false) { var routeOptions = new RouteOptions(); routeOptions.LowercaseUrls = lowerCaseUrls; routeOptions.UseBestEffortLinkGeneration = useBestEffortLinkGeneration; routeOptions.AppendTrailingSlash = appendTrailingSlash; return routeOptions; }
// $Start-RedirectToCanonicalUrl$ /// <summary> /// Adds filters which help improve search engine optimization (SEO). /// </summary> private static void ConfigureSearchEngineOptimizationFilters(ICollection<IFilterMetadata> filters, RouteOptions routeOptions) { filters.Add(new RedirectToCanonicalUrlAttribute( appendTrailingSlash: routeOptions.AppendTrailingSlash, lowercaseUrls: routeOptions.LowercaseUrls)); }
private static DefaultInlineConstraintResolver CreateConstraintResolver() { var services = Mock.Of<IServiceProvider>(); var options = new RouteOptions(); var optionsMock = new Mock<IOptionsAccessor<RouteOptions>>(); optionsMock.SetupGet(o => o.Options).Returns(options); return new DefaultInlineConstraintResolver(services, optionsMock.Object); }
private static DefaultInlineConstraintResolver CreateConstraintResolver() { var options = new RouteOptions(); var optionsMock = new Mock<IOptions<RouteOptions>>(); optionsMock.SetupGet(o => o.Value).Returns(options); return new DefaultInlineConstraintResolver(optionsMock.Object); }
private static VirtualPathContext CreateVirtualPathContext( string routeName = null, ILoggerFactory loggerFactory = null, RouteOptions options = null) { if (loggerFactory == null) { loggerFactory = NullLoggerFactory.Instance; } if (options == null) { options = new RouteOptions(); } var request = new Mock<HttpRequest>(MockBehavior.Strict); var optionsAccessor = new Mock<IOptions<RouteOptions>>(MockBehavior.Strict); optionsAccessor.SetupGet(o => o.Options).Returns(options); var context = new Mock<HttpContext>(MockBehavior.Strict); context.Setup(m => m.RequestServices.GetService(typeof(ILoggerFactory))) .Returns(loggerFactory); context.Setup(m => m.RequestServices.GetService(typeof(IOptions<RouteOptions>))) .Returns(optionsAccessor.Object); context.SetupGet(c => c.Request).Returns(request.Object); return new VirtualPathContext(context.Object, null, null, routeName); }