Open doowruc opened 4 years ago
It appears to be because the HttpContext RouteValues now contains a "version" which is not in the LinkSpec RouteValues.
The following code inserted prior to var path = ctx.LinkGenerator.GetPathByRouteValues(ctx.HttpContext, ctx.LinkSpec.RouteName, ctx.LinkSpec.RouteValues);
fixes it, however this is probably not the best way to include it in the LinkSpec!
var contextRouteValues = ctx.HttpContext.Features.Get<IRouteValuesFeature>()?.RouteValues;
if (contextRouteValues != null && contextRouteValues.ContainsKey("version") && !ctx.LinkSpec.RouteValues.ContainsKey("version"))
{
var version = contextRouteValues["version"];
ctx.LinkSpec.RouteValues.Add("version", version);
}
Further debugging suggests it is because of the lack of getValues
Func being passed on RequireRoutedLink
If I add in version
as the function, then it works, without the need to ament the extension as per my previous comment:
config.AddPolicy<ItemsLinkContainer<ValueInfo>>(policy =>
{
policy.RequireSelfLink()
.RequireRoutedLink("insert", "InsertValueRoute", x => new { version = "1" });
});
I have figured out how to sort this with a LinksHandler
public class VersionLinkRequirement<TResource> : LinksHandler<VersionLinkRequirement<TResource>>, ILinksRequirement
{
public string Id { get; set; }
public string RouteName { get; set; }
public Func<TResource, RouteValueDictionary> GetRouteValues { get; set; }
protected override Task HandleRequirementAsync(LinksHandlerContext context, VersionLinkRequirement<TResource> requirement)
{
if (string.IsNullOrEmpty(requirement.RouteName))
{
context.Skipped(requirement, LinkRequirementSkipReason.Error, $"Requirement did not have a RouteName specified for link: {requirement.Id}");
return Task.CompletedTask;
}
var route = context.RouteMap.GetRoute(requirement.RouteName);
if (route == null)
{
context.Skipped(requirement, LinkRequirementSkipReason.Error, $"No route was found for route name: {requirement.RouteName}");
return Task.CompletedTask;
}
var values = new RouteValueDictionary();
if (requirement.GetRouteValues != null)
{
values = requirement.GetRouteValues((TResource)context.Resource);
}
var link = new LinkSpec(requirement.Id, route, values);
if (context.ActionContext.RouteData.Values.TryGetValue("version", out var version))
{
link.RouteValues.Add("version", version);
}
context.Links.Add(link);
context.Handled(requirement);
return Task.CompletedTask;
}
}
This is great info. Thanks for posting it, hopefully help anyone in future.
Sweet thanks! Any word when this will be pushed to a package?
I have been adding links successfully to a .Net Core 3.1 API project.
Today I have tried to add versioning to my API via the
Microsoft.AspNetCore.Mvc.Versioning
package and am now getting errors inLinkTransformationBuilderExtensions.AddRoutePath
.Specifically,
ctx.LinkGenerator.GetPathByRouteValues()
returns null for insert and delete links.I have added a .Net Core 3.1 sample project to my fork (https://github.com/doowruc/riskfirst.hateoas) which demonstrates the issue. This is a copy of the existing classes in the BasicSimple sample