I'm trying to use dynamic routing in ASP.NET Core. In Startup.cs
I'm setting things up as follows
app.UseRouting()
app.UseEndpoints(endpoints =>
{
endpoints.MapDynamicControllerRoute<PluginSelectorTransformer>("api/{controller}/{action}");
endpoints.MapControllers();
});
My PluginSelectorTransformer
look as follows:
public class PluginSelectorTransformer : DynamicRouteValueTransformer
{
private readonly IPluginSelector pluginSelector;
public PluginSelectorTransformer(IPluginSelector pluginSelector)
{
this.pluginSelector = pluginSelector;
}
public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
{
var controllerName = values["controller"] as string;
var pluginId = pluginSelector.FindPlugin(controllerName);
if (pluginId == null)
return new ValueTask<RouteValueDictionary>(values);
values = new RouteValueDictionary
{
["action"] = "GetPluginConfiguration",
["controller"] = "PluginConfig",
["id"] = pluginId
};
return new ValueTask<RouteValueDictionary>(values);
}
}
And the PluginController
looks like this:
[Route("api/[controller]")]
[ApiController]
public class PluginConfigController :ControllerBase
{
[HttpGet]
[Route("{id}")]
public IActionResult GetPluginConfiguration(Guid id)
{
// implementation omitted
}
[HttpGet]
[Route("{id}/PluginUiConfig")]
public IActionResult GetPluginUiConfig(Guid id)
{
// implementation omitted
}
}
Now, if I run the code and access this URI:
https://localhost:5001/api/SomePlugin/UIConfig
then the transformer does what it's supposed to - pluginId
being dd856ae1-1912-43c0-be70-fb98eb4a7cec, we end up in the same place as if I were to access https://localhost:5001/#/admin/PluginConfig/dd856ae1-1912-43c0-be70-fb98eb4a7cec (so I end up in the GetPluginConfiguration
method as expected).
If I modify the PluginSelectorTransformer
and set action
to "PluginUiConfig" instead of "GetPluginConfiguration", I get a 404 instead.
So, what do I need to change in my PluginSelectorTransformer
to make it work for both cases?
It seems that you didn't set the action to GetPluginUiConfig
, I think you can try adding a new filter in TransformAsync
:
public override ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
{
var controllerName = values["controller"] as string;
var actionName = values["action"] as string;
if (actionName == "UIConfig")
{
// Map the "UIConfig" action to the PluginConfigController
values = new RouteValueDictionary
{
["action"] = "GetPluginUiConfig",
["controller"] = "PluginConfig",
["id"] = values["id"]
};
}
else
{
var pluginId = pluginSelector.FindPlugin(controllerName);
if (pluginId == null)
return new ValueTask<RouteValueDictionary>(values);
values = new RouteValueDictionary
{
["action"] = "GetPluginConfiguration",
["controller"] = "PluginConfig",
["id"] = pluginId
};
}
return new ValueTask<RouteValueDictionary>(values);
}