Model validation in Asp.Net Core before making an Ajax call from java script - ajax

Below is the sample code, i am calling this code on button click event. My question is, can i validate my viewmodel object before making ajax call? i can see model errors in java script, not sure how to check.
My viewmodel class properties has Data Annotation Validator Attributes. I don't want make ajax call if the viewmodel is not valid, want to check (ModelState.IsValid) in java script code, before making ajax call.
Any help, would be greatly appreciated.
$(function () {
$("#btnGet").click(function () {
var viewModelobject = {};
viewModelobject.Name = $("#txtName").val();
$.ajax({
type: "POST",
url: "/Home/AjaxMethod",
data: viewModelobject,
contentType: "application/json",
dataType: "json",
success: function (response) {
alert("Hello")
}
});
});
}

ModelState.IsValid is server side code.Browser has no idea about what it is,so you could not validate ModelState in client side. You can use Jquery Validation at client side.
Here is a working demo:
1.Model:
public class UserModel
{
[Required(ErrorMessage = "The Name field is required.")]
[Display(Name = "Name")]
public string Name { get; set; }
}
2.View(Index.cshtml):
#model UserModel
<form id="frmContact">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" id="txtName" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-secondary" id="btnGet">Click</button>
</div>
</form>
#section Scripts
{
#*you could also add this partial view*#
#*#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}*#
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"></script>
<script>
$(function () {
$('#btnGet').click(function () {
if ($("#frmContact").valid()) {
$('#frmContact').submit();
}
else {
return false;
}
});
$("#frmContact").on("submit", function (event) {
event.preventDefault();
var viewModelobject = {};
viewModelobject.Name = $("#txtName").val();
$.ajax({
type: "POST",
url: "/Home/AjaxMethod",
data: JSON.stringify(viewModelobject),
contentType: "application/json",
dataType: "json",
success: function (response) {
alert("Hello")
}
});
});
})
</script>
}
3.Controller:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult AjaxMethod([FromBody]UserModel user)
{
//do your stuff...
return Json(user);
}
}
Result:

Please use jQuery form validation as shown below inside the button click callback:
var form = $('form[name="' + formName + '"]');
form.validate();
if (form.valid()) {
//Do something if the form is valid
}
else {
//Show validation error messages if the form is in-valid
}

Related

ASP.NET MVC ViewBag values not being displayed in view after Ajax call

I have following view and controller code:
Index.cshtml
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<span style="color:green; font-weight:bold;" id="Message">#ViewBag.Message</span>
<input type="text" id="txtMessage" />
<input type="submit" id="btnSubmit" value="Submit" />
}
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$('#btnSubmit').click(function (event) {
$.ajax({
type: "POST",
url: "/Home/Create",
dataType: "json",
contentType: "application/json; charset=utf-8",
async: false,
data: JSON.stringify({
'message': $('#txtMessage').val()
})
});
});
</script>
Controller code:
public class HomeController : Controller
{
public ActionResult Index(string message)
{
return View();
}
[HttpPost]
public ActionResult Create(string message)
{
ViewBag.Message = message;
return View("Index");
}
}
After clicking the button and making ajax call I'm not able to see the message set in the Create method to ViewBag.Message inside the index view.
If you are using Begin form and button type as submit then why write ajax method?
Remove your btnSubmit click from javascript code and use textbox as TextBoxFor,
#Html.TextBoxFor(m => m.message, new { #class = "form-control" })
it should work.
Update Answer for without strongly type
As per code, you are using Begin Form so not required to ajax call.
So first remove javascript code or if you keep that code so no meaning of that.
Now need to update the following line:
<input type="text" id="txtMessage" **name = "txtMessage"** />
And in the controller code post method the following name should be the same.
[HttpPost]
public ActionResult Create(**string txtMessage**)
{
ViewBag.Message = **txtMessage**;
return View("Index");
}

Ajax Call to PartialViewResult does not Replace Div with PartialView

I've done this dozens of times before and have been testing all morning, I must be missing something very obvious.
I have a form that submits data and if the data already exists, I just want to overwrite that form using a PartialView. I can debug the code and watch the POST get called and I even watch the PartialView reciev its model and data but the PartialView doesn't get rendered on the screen and my AJAX doesn't return anything to the console so I'm not sure how to Troubleshoot this.
My Controller
[HttpPost]
[Route("Send")]
public PartialViewResult Send([FromBody] InstantAlert InstantAlert)
{
string view = "~/views/shared/_InstantAlert_Exists.cshtml";
}
My View
<!-- Form -->
<div id="DivSubmitForm">
<partial name="~/views/home/_Partials/_SubmitForm.cshtml", model="Model" />
</div>
<!-- End Form -->
My Script
$(function () {
$(document).on("click", '#btnSubmit', function () {
if ($('form').valid()) {
Submit();
}
});
function Submit() {
//JSON data
var InstantAlert = {
url: $('#url').val(),
userId: $('#userId').val(),
institutionId: $('#institutionId').val()
}
var jsonToPost = JSON.stringify(InstantAlert);
$.ajax({
url: '/home/Send',
contentType: "application/json; charset=utf-8",
data: jsonToPost,
type: "POST",
success: function (result) {
console.log("Success");
//$('#DivSubmitForm').html(result);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
});
PartialView
<div class="form-group">
<div class="alert alert-danger alert-dismissible" role="alert">
<strong>This article has already been submitted</strong>
<hr class="message-inner-separator">
<p>
test
</p>
</div>
</div>
Argh, so I discovered a form tag on my page which means the controller was inevitably always reloading my initial controller....

Why is my dialog form data not being passed to my controller in my Ajax Post?

I have created a partial view which takes one parameter on a form "email address", and I would like that string passed to my controller called "InviteTeam" which is decorated as an "HttpPost".
so here is the partial view and the ajax command
<form id="inviteTeam">
<label class="sr-only" for="communityCity">Team Email Address</label>
<input class="form-control" type="text" name="teamEmailAddress" id="teamEmailAddress" placeholder="Team Email">
Invite
</form>
<script>
$(document).ready(function () {
$("#btnSubmit").click(function () {
var formdata = $("#inviteTeam").serialize();
alert(formdata);
$.ajax({
type: "POST",
url: "/habitats/InviteTeam",
data: formdata,
success: function () {
$("#inviteModal").modal("hide");
window.location.href = "/Habitats/EditCommunity/"
},
error: function (errorData) { alert(errorData); }
})
});
});
</script>
and here is my controller code: my input string is "email" is null
public ActionResult InviteTeam()
{
return PartialView();
}
[HttpPost]
public ActionResult InviteTeam(string email)
{
return RedirectToAction("EditCommunity", "Habitats");
}
Change name="teamEmailAddress" to name="email" Try the following:
<form id="inviteTeam">
<label class="sr-only" for="communityCity">Team Email Address</label>
<input class="form-control" type="text" name="email" id="teamEmailAddress" placeholder="Team Email">
Invite
</form>
<script>
$(document).ready(function () {
$("#btnSubmit").click(function () {
var formdata = $("#inviteTeam").serialize();
alert(formdata);
$.ajax({
type: "POST",
url: "/habitats/InviteTeam",
data: formdata,
success: function () {
$("#inviteModal").modal("hide");
window.location.href = "/Habitats/EditCommunity/"
},
error: function (errorData) { alert(errorData); }
})
});
});
</script>
Another solution is change the name of the parameter in your action method like:
[HttpPost]
public ActionResult InviteTeam(string teamEmailAddress)
{
return RedirectToAction("EditCommunity", "Habitats");
}
Also if you only want to redirect then you dont need any ajax call. You can simply redirect in javascript as:
window.location.href = "/Habitats/EditCommunity/"
But if you have to do some logic with your email address, then hit that controller action and return JSON as RedirectToAction will not work in AjaxCall like:
return Json("true");
In your success method of Ajax, you can check:
success: function (data) {
if (data == true){
$("#inviteModal").modal("hide");
window.location.href = "/Habitats/EditCommunity/";
}
}

AJAX Post to MVC Controller model every time empty

I am trying to send some data from a modal dialog to my controller with Ajax. But my modelfields are always null, but I enter my actionmethod in the controller.
This is a shortend version of my cshtml-file.
#model anmespace.MyModel
<form method="post" id="formID">
...
<div class="row">
<div class="col-md-5">#Resource.GetResource("MyModal", "Firstname")</div>
<div class="col-md-7"><input type="text" class="form-control" id="firstname" value="#Html.DisplayFor(model => model.FirstName)"></div>
</div>
...
<input type="submit" class="btn btn-primary" value="Submit" />
</form>
<script>
$("#formID").on("submit", function (event) {
var $this = $(this);
var frmValues = $this.serialize();
$.ajax({
cache: false,
async: true,
type: "POST",
url: "#Url.Action("ActionName", "Controller")",
data: frmValues,
success: function (data) {
alert(data);
}
});
});
</script>
Sorry MVC/Ajax are really new for me.
If you want to bind the form data to model then, the names of HTML elements should match with Model properties.
Note: name attribute value of html input field should match to the property of a model.
When you use form and submit button then it will try to reload the page by posting data to the server. You need to prevent this action. You can do this by returning false on onSubmit event in the Form element.
When you use jquery, do not forget to keep the ajax call/events inside the $(document).ready(function(){}) function.
I have written a simple code which takes First Name as input and makes an ajax call on clicking on submit button.
Html & Jquery Code:
<script>
$(document).ready(function() {
$("#formID").on("submit", function(event) {
var $this = $(this);
var frmValues = $this.serialize();
$.ajax({
cache: false,
async: true,
type: "POST",
url: "#Url.Action("PostData", "Home")",
data: frmValues,
success: function(data) {
alert(data.FirstName);
}
});
});
});
</script>
<div>
<form method="post" id="formID" onsubmit="return false;">
<input id="FirstName" name="FirstName"/>
<input type="submit" value="submit" />
</form>
</div>
My Model :
public class Person
{
public string FirstName { get; set; }
}
Action Method:
public ActionResult PostData(Person person)
{
return Json(new { Success = true, FirstName = person.FirstName });
}
Output:

Post datetime to controller

I am trying to send date to controller using ajax but get's null. why?
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<script src="~/Scripts/jquery-2.2.0.min.js"></script>
<script src="~/Scripts/moment.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/bootstrap-datetimepicker.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$('#datetimepicker1').datetimepicker({ useCurrent: false });
$('#datetimepicker1').on("dp.hide", function (e) {
$.ajax({
url: "/Home/GetData",
type: "POST",
data: JSON.stringify($('#datetimepicker1').data('DateTimePicker').date()),
contentType: "application/json",
success: function (result) { alert('Done') },
error: function (r, e, s) { alert(e) }
});
});
</script>
</div>
</div>
Controller:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult GetData(string test)
{
return View();
}
}
You not passing a name/value pair back to the controller method that matches the parameter name (test) and the is no need to stringify the data. Change the ajax script to
$.ajax({
url: '#Url.Action("GetData", "Home")', // don't hard code your url's
type: "POST",
data: { test: $('#datetimepicker1').data('DateTimePicker').date() },
// contentType: "application/json", delete this
success: function (result) { alert('Done') },
error: function (r, e, s) { alert(e) }
});
And since you posting a DateTime value the controller method should be
[HttpPost]
public ActionResult GetData(DateTime test)
{
return View();
}
This assumes the the date value is in a format that matches the server culture, or in ISO format ('yyyy-MM-dd HH:mm'), for example by using
data: { test: $('#datetimepicker1').data('DateTimePicker').date().format('YYYY-MM-DD HH:mm') },
Note that your method is returning a view, but you not doing anything with the html you return (just displaying an alert)

Resources