public void MatchSingle () { var t = new UriTemplateTable (new Uri ("http://localhost:37564")); t.KeyValuePairs.Add (new KeyValuePair<UriTemplate,object> (new UriTemplate ("/jsdebug"), null)); Assert.IsNull (t.MatchSingle (new Uri ("http://localhost:37564/js")), "#1"); Assert.IsNotNull (t.MatchSingle (new Uri ("http://localhost:37564/jsdebug")), "#2"); }
public static void Main() { Uri prefix = new Uri("http://localhost/"); //A UriTemplateTable is an associative set of UriTemplates. It lets you match //candidate URI's against the templates in the set, and retrieve the data associated //with the matching templates. //To start, we need some example templates and a table to put them in: UriTemplate weatherByCity = new UriTemplate("weather/{state}/{city}"); UriTemplate weatherByState = new UriTemplate("weather/{state}"); UriTemplate traffic = new UriTemplate("traffic/*"); UriTemplate wildcard = new UriTemplate("*"); UriTemplateTable table = new UriTemplateTable(prefix); //Now we associate each template with some data. Here we're just using strings; //you can associate anything you want with the template. table.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(weatherByCity, "weatherByCity")); table.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(weatherByState, "weatherByState")); table.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(traffic, "traffic")); //Once the table is populated, we can use the MatchSingle function to //retrieve some match results: UriTemplateMatch results = null; Uri weatherInSeattle = new Uri("http://localhost/weather/Washington/Seattle"); //The Match function will select the best match for the incoming URI //based on the templates in the table. There are two variants of Match -- //Match() can potentially return multiple results, which MatchSingle() will //either return exactly one result or throw an exception. results = table.MatchSingle(weatherInSeattle); //We get back the associated data in the Data member of //the UriTemplateMatchResults that are returned. if (results != null) { //Output will be "weatherByCity" Console.WriteLine(results.Data); //The UriTemplateMatch contains useful data obtained during the //matching process. Console.WriteLine("State: {0}", results.BoundVariables["state"]); Console.WriteLine("City: {0}", results.BoundVariables["city"]); } Console.WriteLine("Press any key to terminate"); Console.ReadLine(); }
/// <summary> /// Executes if the current request is processed by ASP.NET on the begin of request. /// Rewrites the Url if there IIS is configured for extensionless Urls. /// </summary> /// <param name="sender">The current <see cref="HttpApplication" />.</param> /// <param name="e">The EventArgs.</param> private void context_BeginRequest(object sender, EventArgs e) { // Get the current HTTP context. var context = ((HttpApplication)sender).Context; // Get the navigation service. var navigationService = this.Container.Resolve<INavigationService>(); // Get the url from the current request. var currentPath = context.Request.Url; // Set up the table with the URI templates. var uriTemplateTable = new UriTemplateTable(); // Set the table's base address. uriTemplateTable.BaseAddress = new Uri(navigationService.GetApplicationPath()); // Set the rules. uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetDownloadUriTemplate() + "{data}"), HandlerAction.Download)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetRedirectUriTemplate() + "{data}"), HandlerAction.Redirect)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetSecurityTokenServiceUriTemplate()), HandlerAction.SecurityTokenService)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetSecurityTokenServiceUriTemplate().TrimEnd('/')), HandlerAction.SecurityTokenService)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetSecurityTokenServiceUriTemplate() + "{data}"), HandlerAction.SecurityTokenService)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate().TrimEnd('/')), HandlerAction.UI)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate()), HandlerAction.UI)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}"), HandlerAction.UI)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/"), HandlerAction.UI)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/{controllerAction}"), HandlerAction.UI)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/{controllerAction}/"), HandlerAction.UI)); uriTemplateTable.KeyValuePairs.Add(new KeyValuePair<UriTemplate, object>(new UriTemplate(navigationService.GetUIUriTemplate() + "{controller}/{controllerAction}/{data}"), HandlerAction.UI)); // Check whether the current path matches any of these rewrite rules. If not, return. UriTemplateMatch uriTemplateMatch = uriTemplateTable.MatchSingle(currentPath); if (uriTemplateMatch == null) { // Before returning, check whether silkveil.net's application handler was called // directly. If so, check if SSL is required for silkveil.net, and redirect, if // neccessary. if (context.Request.Url.GetLeftPart(UriPartial.Path).TrimEnd('/').ToLowerInvariant() == navigationService.GetApplicationHandlerFactoryPath().TrimEnd('/').ToLowerInvariant()) { this.Container.Resolve<IProtocolManager>().RedirectIfNeccessary(context.Request); } // Return to the caller. return; } // Check if SSL is required for silkveil.net, and redirect, if neccessary. this.Container.Resolve<IProtocolManager>().RedirectIfNeccessary(context.Request); // Otherwise, redirect using the URI match. var applicationHandlerFactoryVirtualPath = navigationService.GetApplicationHandlerFactoryVirtualPath(); switch ((HandlerAction)uriTemplateMatch.Data) { case HandlerAction.Download: context.RewritePath(string.Format(CultureInfo.InvariantCulture, applicationHandlerFactoryVirtualPath + "?Action={0}&Data={1}", HandlerAction.Download, uriTemplateMatch.BoundVariables["data"])); break; case HandlerAction.Redirect: context.RewritePath(string.Format(CultureInfo.InvariantCulture, applicationHandlerFactoryVirtualPath + "?Action={0}&Data={1}", HandlerAction.Redirect, uriTemplateMatch.BoundVariables["data"])); break; case HandlerAction.SecurityTokenService: string data = uriTemplateMatch.BoundVariables["data"] ?? "Logon"; string wa; switch (data) { case "Logon": wa = WSFederationConstants.Actions.SignIn; break; case "Logoff": wa = WSFederationConstants.Actions.SignOut; break; default: throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, "The data '{0}' is not supported.", data)); } var wtrealm = "http://www.silkveil.net/"; context.RewritePath(string.Format(CultureInfo.InvariantCulture, applicationHandlerFactoryVirtualPath + "?Action={0}&Data={1}&wa={2}&wtrealm={3}", HandlerAction.SecurityTokenService, data, wa, HttpUtility.UrlEncode(wtrealm))); break; case HandlerAction.UI: context.RewritePath(string.Format(CultureInfo.InvariantCulture, applicationHandlerFactoryVirtualPath + "?Action={0}&Controller={1}&ControllerAction={2}&Data={3}", HandlerAction.UI, uriTemplateMatch.BoundVariables["controller"] ?? string.Empty, uriTemplateMatch.BoundVariables["controllerAction"] ?? string.Empty, uriTemplateMatch.BoundVariables["data"] ?? string.Empty)); break; } }
bool ShouldRedirectToUriWithSlashAtTheEnd(UriTemplateTable methodSpecificTable, Message message, Uri to) { UriBuilder ub = new UriBuilder(to); if (ub.Path.EndsWith("/", StringComparison.Ordinal)) { return false; } ub.Path = ub.Path + "/"; Uri originalPlusSlash = ub.Uri; bool result = false; if (methodSpecificTable != null && methodSpecificTable.MatchSingle(originalPlusSlash) != null) { // as an optimization, we check the table that matched the request's method // first, as it is more probable that a hit happens there result = true; } else { // back-compat: // we will redirect as long as there is any method // - not necessary the one the user is looking for - // that matches the uri with a slash at the end foreach (KeyValuePair<string, UriTemplateTable> pair in methodSpecificTables) { UriTemplateTable table = pair.Value; if (table != methodSpecificTable && table.MatchSingle(originalPlusSlash) != null) { result = true; break; } } } if (result) { string hostAndPort = GetAuthority(message); originalPlusSlash = UriTemplate.RewriteUri(ub.Uri, hostAndPort); message.Properties.Add(RedirectPropertyName, originalPlusSlash); } return result; }
bool CanUriMatch(UriTemplateTable methodSpecificTable, Uri to, HttpRequestMessageProperty prop, Message message, out string operationName) { operationName = null; UriTemplateMatch result = methodSpecificTable.MatchSingle(to); if (result != null) { operationName = result.Data as string; Fx.Assert(operationName != null, "bad result"); AddUriTemplateMatch(result, prop, message); return true; } return false; }
public void MatchSingleNoPair () { var t = new UriTemplateTable (new Uri ("http://localhost:37564")); // at least one UriTemplate must exist in the table. t.MatchSingle (new Uri ("http://localhost:37564")); }
public static void Main() { Uri prefix = new Uri("http://localhost/"); //One interesting use for UriTemplateTable is as a dispatching engine. //This is accomplished by using the UriTemplateTable to associate //a delegate handler with each UriTemplate. //To start, we need a UriTemplateTable. UriTemplateTable table = new UriTemplateTable(prefix); //Now, we add templates to the table and associate them //with handler functions, written as anonymous delegates: AddHandler(table, new UriTemplate("weather/{state}/{city}"), delegate(UriTemplateMatch r) { Console.WriteLine("Matched the WeatherByCity template"); Console.WriteLine("State: {0}", r.BoundVariables["state"]); Console.WriteLine("City: {0}", r.BoundVariables["city"]); }); AddHandler(table, new UriTemplate("weather/{state}"), delegate(UriTemplateMatch r) { Console.WriteLine("Matched the WeatherByState template"); Console.WriteLine("State: {0}", r.BoundVariables["state"]); }); AddHandler(table, new UriTemplate("traffic/*"), delegate(UriTemplateMatch r) { Console.WriteLine("Matched the traffic/* template"); Console.WriteLine("Wildcard segments:"); foreach (string s in r.WildcardPathSegments) { Console.WriteLine(" " + s); } }); //MakeReadOnly() freezes the table and prevents further additions. //Passing false to this method will disallow duplicate URI's, //guaranteeing that at most a single match will be returned. //Calling this method explictly is optional, as the collection //will be made read-only during the first call to Match() or MatchSingle() table.MakeReadOnly(false); Uri request = null; //Match WeatherByCity request = new Uri("http://localhost/weather/Washington/Seattle"); Console.WriteLine(request); InvokeDelegate(table.MatchSingle(request)); //Match WeatherByState request = new Uri("http://localhost/weather/Washington"); Console.WriteLine(request); InvokeDelegate(table.MatchSingle(request)); //Wildcard match Traffic request = new Uri("http://localhost/Traffic/Washington/Seattle/SR520"); Console.WriteLine(request); InvokeDelegate(table.MatchSingle(request)); Console.WriteLine("Press any key to terminate"); Console.ReadLine(); }