Add sample to "select" an address and generate a URL (#434)
Addresses #428
This commit is contained in:
parent
ebd0baa458
commit
6b2ccdead8
|
|
@ -8,6 +8,8 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Dispatcher\Microsoft.AspNetCore.Dispatcher.csproj" />
|
<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.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>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// 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 System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Dispatcher;
|
using Microsoft.AspNetCore.Dispatcher;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace DispatcherSample
|
namespace DispatcherSample
|
||||||
|
|
@ -15,6 +15,8 @@ namespace DispatcherSample
|
||||||
{
|
{
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
services.AddSingleton<UrlGenerator>();
|
||||||
|
services.AddSingleton<RouteValueAddressTable>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||||
|
|
@ -55,9 +57,12 @@ namespace DispatcherSample
|
||||||
{
|
{
|
||||||
if (dictionary.TryGetValue(context.Request.Path, out var value))
|
if (dictionary.TryGetValue(context.Request.Path, out var value))
|
||||||
{
|
{
|
||||||
var dispatcherFeature = new DispatcherFeature();
|
var dispatcherFeature = new DispatcherFeature
|
||||||
dispatcherFeature.Endpoint = value.Endpoint;
|
{
|
||||||
dispatcherFeature.RequestDelegate = value.RequestDelegate;
|
Endpoint = value.Endpoint,
|
||||||
|
RequestDelegate = value.RequestDelegate
|
||||||
|
};
|
||||||
|
|
||||||
context.Features.Set<IDispatcherFeature>(dispatcherFeature);
|
context.Features.Set<IDispatcherFeature>(dispatcherFeature);
|
||||||
await context.Response.WriteAsync("<p>Dispatch</p>");
|
await context.Response.WriteAsync("<p>Dispatch</p>");
|
||||||
await next.Invoke();
|
await next.Invoke();
|
||||||
|
|
@ -70,10 +75,18 @@ namespace DispatcherSample
|
||||||
await next.Invoke();
|
await next.Invoke();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.Run(async (context) =>
|
app.Use(async (context, next) =>
|
||||||
{
|
{
|
||||||
var feature = context.Features.Get<IDispatcherFeature>();
|
var feature = context.Features.Get<IDispatcherFeature>();
|
||||||
await feature.RequestDelegate(context);
|
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>");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue