I create a web application with Razor Pages.
I have 2 Models with one to many relationship: one List
can hold many Records
.
public class List
{
public int ID { get; set; }
[StringLength(25, MinimumLength = 3, ErrorMessage = "Title should be in range between 3 and 25")]
[Display(Name = "Title")]
public string Caption { get; set; }
public string UserId { get; set; }
public User User { get; set; }
public ICollection<Record> Records { get; set; }
}
public class Record
{
public int ID { get; set; }
[StringLength(25, MinimumLength = 3, ErrorMessage = "Word should be in range between 3 and 25")]
[Display(Name = "Title")]
public string Word { get; set; }
[StringLength(30, MinimumLength = 3, ErrorMessage = "Translation should be in range between 3 and 30")]
public string Translation { get; set; }
public int ListId { get; set; }
public List List { get; set; }
}
I need to provide navigation from List
item to List of Record
in the similar way as it is possible in Web API or in MVC. In Microsoft documentation I found the page about attributes in Web Api, that behaviour that I need:
[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }
I need something like this:
[Microsoft.AspNetCore.Mvc.Route("Lists/{listId}/Records")]
public async Task GetRecordsByList(int listId)
{
var allRecords = await _context.Record.ToListAsync();
Record = allRecords.Where(w => w.ListId == listId).ToList() ;
}
I am sure that is possible to provide navigation from parent model List
to a child items List of Record
.
UI will be like this:
From Lists
Desired URL should be like this:
I am sure somebody faced the same issue and fixed that! I will be very grateful for any help or advise.
Razor Pages uses attribute routing by default. Routes are generated from the file paths of individual pages. You can specify parameters for routes, but you do this for a specific page by adding a route template to the @page
directive.
The first page that you show can either be a page named Lists.cshtml or a page named Index.cshtml in a Lists folder. Either way, it will be available at domain.com/lists
using the default routing. The second page can be a page named Details.cshtml with an override route template of "/Lists/{listid}/Records"
:
@page "/Lists/{listid}/Records"
Or you can use the AddPageRoute
method in Startup to add another route by which the Index page can be reached:
services.AddMvc().AddRazorPagesOptions(options =>
{
options.Conventions.AddPageRoute("/Lists/Index", "Lists/{listid}/Records");
});
Although that would require code in Index to determine whether it should be showing all lists or details of a selected list.
Personally, I recommend the first approach. In Razor Pages, you should aim to keep each page down to one responsibility.
See more about Razor Pages routing here: https://www.learnrazorpages.com/razor-pages/routing