3
votes

I have met a weird situation in one of my Asp.Net Core projects using Razor Pages.
Simply put I have a form with two submit buttons. One of them is used to save the form and go back to the home page, the second one is used to save the form and then reinitialize the Model BindedProperty to insert again another document (a Save and repeat scenario).

The first submit button has no page-handler defined and should call, by convention, the predefined OnPostAsync method on the PageModel file, the second one instead has a asp-page-handler="SaveAndRepeat" and should call a custom page handler method named OnPostSaveAndRepeatAsync.

This is the cshtml code without all the divs and inputs.

<form method="POST">
    ... a lot of html and tags ...
    <button id="insert-doc-button" type="submit" class="btn btn-primary">Save</button>
    <button id="insert-repeat-doc-button" type="submit" asp-page-handler="SaveAndRepeat" class="btn btn-primary">Save and Repeat</button>            }
</form>

This is the stripped down code in the PageModel file that responds to the submits

    [BindedProperty]
    DocumentVM CurrentDoc {get;set;}
    .....
    
    public async Task<IActionResult> OnPostAsync()
    {
        try
        {
            bool saved = await CommonSave();
            ......
            return RedirectToPage("/index");
        }
        ....
    }
    public async Task<IActionResult> OnPostSaveAndRepeatAsync()
    {
        try
        {
            bool saved = await CommonSave();
            ...
            // Duplicates the BindedProperty
            CurrentDoc = CurrentDoc.Duplicate();
            return Page();
        }
        ....
    }

Now the problem. As you can see, after calling SaveAndRepeat the PageModel code returns to the same Page with the BindedProperty loaded with values duplicated from the last save. (And it works as expected) But now, if I try to press the Save button (because I have reached the last document to insert) the code calls again the OnPostSaveAndRepeatAsync handler and not the default OnPostAsync. Of course this doesn't happen if I just press the Save button because I have only one document to insert. In this case the code calls correctly the OnPostAsync.

To be honest I am not a very expert on this technology, just starting my first projects now but this seems like I have not understood something important. And yes, I have resolved the problem setting an asp-page-handler also for the Save button, however I am really curious to know the reason of this behavior.

I need to add also that this project uses ASP.NET Core 3.0 due to a restriction imposed by the ISP that has not yet enabled the 3.1 version on its hosting servers.

1

1 Answers

1
votes

If you click the OnPost method first it works because there isn't any handler on your route.

Whenever you use asp-page-handler, the name of the handler is getting added to your route as a query string parameter, you can check it on your browser.

1

After that, you're calling the default OnPost, which doesn't require any handler parameters and isn't modifying them, that makes Razor Pages think that you're calling the post with the SaveAndRepeat handler again, so it gets redirected to your OnPostSaveAndRepeatAsync method.

Clicking on a button with a different asp-page-handler changes the handler parameter on your query string, making it call the specified method.