First of all try to validate on the client first to prevent unnecessary postbacks. You can use attributes to set validation:
using System.ComponentModel.DataAnnotations;
public class ForgotPasswordViewModel()
{
[Required]
[EmailAddress]
public string Email { get; set; }
}
In the view check the Modelstate:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
Of course client side isn't enough, so in case the client side validation is skipped the server makes sure that the model validates.
One way to scroll to a position is to use an anchor. The anchor is a client side way to bookmark parts in the document. Normally you would see something like this:
<a href"home#contact">Contact</a>
By clicking the link you would scroll to the contact
bookmark in the home document. You can do the same for the post:
<div id="contact">
<form method="post" action="home#contact">
@Html.AntiForgeryToken()
</form>
</div>
In case of an error the page will automatically scroll to the form, since on the client the #contact
hash was set. The assumption is that in case of success you redirect to another view. This is afaik the only way to scroll without the use of javascript. And since javascript validation didn't work...
Please note that with .Net Core AntiForgery is added automatically if you use the tag helper. But since I didn't use it I have to add this myself.
There are other options that involve javascript or some server side redirection, but I think this is an easy solution.
I do not know if partial page refresh is the best solution. I think it depends. There are plenty of examples available on how you can post asynchronous. Check this link: https://www.w3schools.com/jquery/ajax_ajax.asp