I am working with a single page layout that has a contact form. The code seems to fire correctly and sends the form values to the page model, and then it reloads the page. What I want to happen is to be able to submit the form values to the page model without reloading the form page.
Can someone show me how to do this?
Page Model
public class IndexModel : PageModel
{
[BindProperty]
public ContactModel Contact { get; set; }
public void OnGet()
{
}
public void OnPostSendEmail()
{
if (ModelState.IsValid == false)
{
}
else
{
}
}
}
Page Form
<form method="post" role="form" class="email-form">
<div class="form-row">
<div class="form-group col-md-6">
<label for="name">Your Name</label>
<input type="text" asp-for="Contact.Name" value="Gekko" name="name" class="form-control" id="name" data-rule="minlen:4" data-msg="Please enter at least 4 chars" />
<div class="validate"></div>
</div>
<div class="form-group col-md-6">
<label for="name">Your Email</label>
<input type="email" asp-for="Contact.Email" value="someone@email.com" class="form-control" name="email" id="email" data-rule="email" data-msg="Please enter a valid email" />
<div class="validate"></div>
</div>
</div>
<div class="form-group">
<label for="name">Subject</label>
<input type="text" asp-for="Contact.Subject" value="Work" class="form-control" name="subject" id="subject" data-rule="minlen:4" data-msg="Please enter at least 8 chars of subject" />
<div class="validate"></div>
</div>
<div class="form-group">
<label for="name">Message</label>
<textarea class="form-control" asp-for="Contact.Message" name="message" rows="10" data-rule="required" data-msg="Please write something for us"></textarea>
<div class="validate"></div>
</div>
<div class="mb-3">
<div class="loading">Loading</div>
<div class="error-message"></div>
<div class="sent-message">Your message has been sent. Thank you!</div>
</div>
<div class="text-center"><button id="submit">Send Message</button></div>
</form>
JavaScript
$('form.email-form').submit(function (e) {
e.preventDefault();
...some form validation
$.ajax({
type: "POST",
url: '/index?handler=SendEmail',
data: str,
success: function(msg) {
if (msg == 'OK') {
this_form.find('.loading').slideUp();
this_form.find('.sent-message').slideDown();
this_form.find("input:not(input[type=submit]), textarea").val('');
} else {
this_form.find('.loading').slideUp();
this_form.find('.error-message').slideDown().html(msg);
}
}
});
Razor Pages are designed to be automatically protected from cross-site request forgery (CSRF/XSRF) attacks. So the first thing is to modify your ajax to include token in header:
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
And configure the antiforgery service to look for the X-CSRF-TOKEN header :
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
Below article is for your reference :
Handle Ajax Requests in ASP.NET Core Razor Pages
And OnPostSendEmail
is void type so no value returned, if you want to return something from server side and fill html in success function of ajax , you can return JsonResult
in OnPostSendEmail
method.