Search code examples
c#asp.netasp.net-mvcasp.net-web-api-routingrazor-pages

Razor Page Routing in the same way as in Web API


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 enter image description here

Navigate to Records: enter image description here

Desired URL should be like this:

enter image description here

I am sure somebody faced the same issue and fixed that! I will be very grateful for any help or advise.


Solution

  • 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