I'm building a system using ASP.NET Core 2.0 Razor Pages (not MVC) and I'm having trouble adding multiple routes for pages. For example, all pages should be able to be reached by abc.com/language/segment/shop/mypage or abc.com/language/shop/mypage, where both paths point to the same page. The segment path section is optional, then the pages do stuff with the optional segment info.
The question mark syntax in the CombineTemplates markup doesn't seem to work, it seems to only work in the last section of the path. Browsing to a url without a value in the {segment?} section resulted in 404. For example:
AttributeRouteModel.CombineTemplates("{language}/{segment?}/shop", selector.AttributeRouteModel.Template);
I tried code like this below but it only appends the two paths to each other, and I need to be able to enable them both as valid.
options.Conventions.Add(new DefaultPageRouteModelConvention());
options.Conventions.Add(new SegmentPageRouteModelConvention());
In ASP.NET MVC, I could just add two different routes pointing to the same area/controller/action with two different named MapRouteWithName. Any ideas how to do this with .NET Razor Page syntax?
you can do it in the client side, in javascript. Also create an anchor a set the asp-controller and asp-action and there you redirect. Or create an anchor a and hard code the path.
UseEndpoints adds endpoint execution to the middleware pipeline. It runs the delegate associated with the selected endpoint.
You can add support for Pages to any ASP.NET Core MVC app by simply adding a Pages folder and adding Razor Pages files to this folder. Razor Pages use the folder structure as a convention for routing requests.
This code works:
Add a single convention (not two different conventions):
options.Conventions.Add(new CombinedPageRouteModelConvention());
In the new convention, add both route selectors:
private class CombinedPageRouteModelConvention : IPageRouteModelConvention
{
private const string BaseUrlTemplateWithoutSegment = "{language}/shop";
private const string BaseUrlTemplateWithSegment = "{language}/{segment}/shop";
public void Apply(PageRouteModel model)
{
var allSelectors = new List<SelectorModel>();
foreach (var selector in model.Selectors)
{
//setup the route with segment
allSelectors.Add(CreateSelector(selector, BaseUrlTemplateWithSegment));
//setup the route without segment
allSelectors.Add(CreateSelector(selector, BaseUrlTemplateWithoutSegment));
}
//replace the default selectors with new selectors
model.Selectors.Clear();
foreach (var selector in allSelectors)
{
model.Selectors.Add(selector);
}
}
private static SelectorModel CreateSelector(SelectorModel defaultSelector, string template)
{
var fullTemplate = AttributeRouteModel.CombineTemplates(template, defaultSelector.AttributeRouteModel.Template);
var newSelector = new SelectorModel(defaultSelector)
{
AttributeRouteModel =
{
Template = fullTemplate
}
};
return newSelector;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With