Add sample to "select" an address and generate a URL (#434)

Addresses #428
This commit is contained in:
Jass Bagga 2017-09-01 14:02:16 -07:00 committed by GitHub
parent ebd0baa458
commit 6b2ccdead8
5 changed files with 128 additions and 5 deletions

View File

@ -8,6 +8,8 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Dispatcher\Microsoft.AspNetCore.Dispatcher.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Dispatcher.Abstractions\Microsoft.AspNetCore.Dispatcher.Abstractions.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing.Abstractions\Microsoft.AspNetCore.Routing.Abstractions.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Routing\Microsoft.AspNetCore.Routing.csproj" />
</ItemGroup>

View File

@ -0,0 +1,22 @@
using System;
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Dispatcher;
using Microsoft.AspNetCore.Routing;
namespace DispatcherSample
{
public class RouteValueAddress : Address
{
public RouteValueAddress(string displayName, RouteValueDictionary dictionary)
{
DisplayName = displayName;
RouteValueDictionary = dictionary;
}
public override string DisplayName { get; }
public RouteValueDictionary RouteValueDictionary { get; set; }
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.AspNetCore.Routing;
namespace DispatcherSample
{
public class RouteValueAddressTable
{
public IList<RouteValueAddress> Addresses
{
get
{
var addresses = new List<RouteValueAddress>
{
new RouteValueAddress("Mickey", new RouteValueDictionary (new { Character = "Mickey" })),
new RouteValueAddress("Hakuna Matata", new RouteValueDictionary (new { Movie = "The Lion King"})),
new RouteValueAddress("Simba", new RouteValueDictionary (new { Movie = "The Lion King", Character = "Simba" })),
new RouteValueAddress("Mufasa", new RouteValueDictionary (new { Movie = "The Lion King", Character = "Mufasa" })),
new RouteValueAddress("Aladdin", new RouteValueDictionary (new { Movie = "Aladdin", Character = "Genie" })),
};
return addresses;
}
}
}
}

View File

@ -1,12 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Dispatcher;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
namespace DispatcherSample
@ -15,6 +15,8 @@ namespace DispatcherSample
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<UrlGenerator>();
services.AddSingleton<RouteValueAddressTable>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
@ -55,9 +57,12 @@ namespace DispatcherSample
{
if (dictionary.TryGetValue(context.Request.Path, out var value))
{
var dispatcherFeature = new DispatcherFeature();
dispatcherFeature.Endpoint = value.Endpoint;
dispatcherFeature.RequestDelegate = value.RequestDelegate;
var dispatcherFeature = new DispatcherFeature
{
Endpoint = value.Endpoint,
RequestDelegate = value.RequestDelegate
};
context.Features.Set<IDispatcherFeature>(dispatcherFeature);
await context.Response.WriteAsync("<p>Dispatch</p>");
await next.Invoke();
@ -70,10 +75,18 @@ namespace DispatcherSample
await next.Invoke();
});
app.Run(async (context) =>
app.Use(async (context, next) =>
{
var feature = context.Features.Get<IDispatcherFeature>();
await feature.RequestDelegate(context);
await next.Invoke();
});
app.Run(async (context) =>
{
var urlGenerator = app.ApplicationServices.GetService<UrlGenerator>();
var url = urlGenerator.GenerateURL(new RouteValueDictionary(new { Movie = "The Lion King", Character = "Mufasa" }), context);
await context.Response.WriteAsync($"<p>Generated url: {url}</p>");
});
}
}

View File

@ -0,0 +1,58 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
namespace DispatcherSample
{
public class UrlGenerator
{
private readonly RouteValueAddressTable _addressTable;
public UrlGenerator(RouteValueAddressTable addressTable)
{
_addressTable = addressTable;
}
//Find match from values to a template
public string GenerateURL(RouteValueDictionary routeValues, HttpContext context)
{
var address = FindAddress(_addressTable, routeValues);
return $"RouteName: {address.DisplayName} URL: /{address.RouteValueDictionary["Character"]}/{address.RouteValueDictionary["Movie"]}";
}
//Look up the Addresses table
private RouteValueAddress FindAddress(RouteValueAddressTable addressTable, RouteValueDictionary routeValues)
{
var addressMatch = new RouteValueAddress(null, new RouteValueDictionary());
foreach (var address in addressTable.Addresses)
{
foreach (var key in address.RouteValueDictionary.Keys)
{
if (!routeValues.Keys.Contains(key))
{
addressMatch.RouteValueDictionary.Clear();
break;
}
if (routeValues.Values.Contains(address.RouteValueDictionary[key]))
{
addressMatch.RouteValueDictionary[key] = routeValues[key];
}
}
if (addressMatch.RouteValueDictionary.Count == routeValues.Count)
{
return new RouteValueAddress(address.DisplayName, address.RouteValueDictionary);
}
else
{
addressMatch.RouteValueDictionary.Clear();
}
}
return addressMatch;
}
}
}