IAdam
IAdam

Reputation: 37

Inherited razor page OnPostAsync - Multiple handlers matched

I have encountered an issue with my new test project when I inherit a razor page from another. So I had an editor page and I wanted to use the same flow just with gave an extra param (id), the code was:

public class EditModel : BaseModel
{
    public EditModel() 
    {
    }

    public Task<IActionResult> OnPostAsync(int id)
    {
        ...
    }
}

public class CreateModel : EditModel
{
    public CreateModel()
    {

    }

    public Task<IActionResult> OnPostAsync()
    {
        ...
    }
}

Also I defined the editor cshtml as:

@page "{id:int}"
...

and the create cshtml as:

@page
...

I would expect that the routing was obvious cuz editor's parameter is NOT optional, but create does not need a parameter, but I got the error:

Multiple handlers matched

If I define parameter in create page model too it starts working with 0 value.

I have two questions about that:

Can I define a routing template where I can explicitly forbid the parameter (and how) to avoid ambiguity? (Now I'm using default routing template.)

Shoud I avoid this kind of inheritance of razor pages? I can except that if it is by design and use another way to do it.

I would like to mention that I know I can define another handler methods different from default onget/onpost/etc and use it this way, however I think the above problem should work properly if I can define the routing in a good way.

Upvotes: 2

Views: 1730

Answers (1)

Nidust
Nidust

Reputation: 619

Hi and welcome to the board! Before digging more about your purposes for this design, let first make something clear about the scenario.

  • You are probably using ASP.NET Core Razor Page, but you ended up with this line EditModel : BaseModel so I assume that there must be something like BaseModel : PageModel
  • Next thing I know that you make another inheritance which is CreateModel : EditModel and this time it bugged me out because this obviously will make EditModel inherit a method so-called Task<IActionResult> OnPostAsync(int id) because that what inheritance do!

For example:

public class Test1
{
    public void sayHello(){
        Console.WriteLine("hehe");
    }
}

public class Test2 : Test1
{
    public void sayHello(string inputValue){
        Console.WriteLine(inputValue);
    }
}

and the result when you have something like

Test2 test = new Test2();
test.sayHello();
test.sayHello("something");

The result would be

hehe
something

Once again, I'm not sure about your purposes on this methodology, so it would be nice if you can share some though so we both can evolve in something new.

UPDATE: At this point, I understand that you created a problem for a case study. So let see if I came up with something right.

.NET core allows you to define some specific route inside Startup.cs beside the default routing, which obviously won't fit in this case.

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .AddRazorPagesOptions(options =>
        {
            options.Conventions.AddPageRoute("/edit", "{handler?}/{id?}");
            options.Conventions.AddPageRoute("/create", "{handler?}");
        });
}

Now, I believe if you put @page "{id:int}" in your .cshtml page, it would run as expected.

Upvotes: 1

Related Questions