Reputation: 3823
I have a class in my project which looks like this:
public class MyClass
{
[Required]
public string keyword { get; set; }
public string saleRange { get; set; }
}
This is how the action looks like:
[HttpPost]
[ActionName("Analyze")]
public ActionResult Analyze(MyClass obj)
{
if (!ModelState.IsValid)
{
return Json("error");
}
else
{
return Json("ok");
}
}
And in jQuery:
$(document).on("click",".btnAnalyze",function() {
var data =
{
keyword: $(".keywordInput").val(),
saleRange: "1"
};
console.log($(".keywordInput").val());
$.post("/Controller/Analyze",data).done(function(){
if (data == "error") {
alert("all fields are required");
}
});
});
As you can see I'm mapping a JS object to a C# class object which I pass to my action. Now what the problem here is, even if I don't supply anything for the keyword property (ie. it's null or ""), the ModelState still shows it's property IsValid as true, but it should be set on false if I don't pass anything as keyword parameter.
This is first part of the problem, the other question I have here is how would I, If I have 10 textbox field, of which all are required. And if user enters only 1/10 of those, I would like to send a message for the first next field user has to validate in order to proceed, like "texbox #2 is required, please enter something" instead of a just general message like "all fields are required" or something like that ?
Can someone help me out with this ?
Why does the modelstate shows the it's valid even though after I dont' supply keyword parameter in the object?
@T.Jung here Is a sample of input:
<input placeholder="Enter keywords" class="form-control keywordInput" type="text" style="width:80%">
It's basically just a plain input field in html..
Upvotes: 1
Views: 1590
Reputation: 3657
If you want to do the Validation on server side:
Contoller:
[HttpPost]
[ActionName("Analyze")]
public ActionResult Analyze(Model viewModel)
{
if(viewModel.PropertyName.IsNullOrEmpty()){
{
ModelState.AddModelError("PropertyName", "The Field InputFieldName neeeds to be filled!");
}
if (ModelState.IsValid)
{
//Do what ever you want with your Inofrmation
//return a redirct or anything else
}
//If you got here some fields are not filled
return View(viewModel);
}
View:
@Html.TextBoxFor(x => x.PropertyName)
@Html.ValidationMessageFor(m => m.PropertyName, "", new { @class = "text-danger" })
//@class = "text-danger" only if you're using bootstrap
I do all of my validation this way.
Upvotes: 0
Reputation: 58462
I would do the following:
Make sure your script bundle includes the following 2 files after your jquery and in this order:
Create your partial / view for your form:
@model MyClassObject
<form action="/action" method="post" id="form">
<div class="row">
@Html.ValidationMessageFor(m => m.Param1)
@Html.LabelFor(m => m.Param1, new { @class = "label" })
@Html.TextBoxFor(m => m.Param1, new { @class = "textbox" })
</div>
<div class="row">
@Html.ValidationMessageFor(m => m.Param2)
@Html.LabelFor(m => m.Param2, new { @class = "label" })
@Html.TextBoxFor(m => m.Param2, new { @class = "textbox" })
</div>
<div class="row">
@Html.ValidationMessageFor(m => m.Param3)
@Html.LabelFor(m => m.Param3, new { @class = "label" })
@Html.TextBoxFor(m => m.Param3, new { @class = "textbox" })
</div>
<input type="submit" value="submit">
</form>
[HttpPost]
[ActionName("action")]
public ActionResult action(MyClassObject obj)
{
if(!ModelState.IsValid)
{
return action(); // this is your original action before you do the post
}
else
{
// do your processing and return view or redirect
return View(); // or redirect to a success page
}
}
public class MyClassObject
{
[Required(ErrorMessage = "Please enter a keyword")]
public string keyword { get; set; }
public string saleRange { get; set; }
}
var form = document.getElementById('form'), // get a normal js form (I do this just so I can pass in the method and action dynamically - seems better than using .attr() to get them
jqForm = $(form);
jqForm.on('submit', function(e) {
e.preventDefault();
if (jqForm.valid()) {
var formData = jqForm.serializeArray(); // I use serializeArray so I can add extra values if I need to, you can use serialize()
// formData.push({ name: this.name, value: this.value }); - optional for adding extra data
$.ajax({
url: form.action, // this can be just a specific json url if you just need to get some json - it doesn't have to be the same url as the fallback (no js url)
type: form.method,
data: formData,
success: function(result) {
// do success stuff!
}
});
}
})
Upvotes: 3
Reputation: 1925
You can use form validation, which will perform data annotation validation on the client side and you do not have to go to the server side.
$('#btnAnalyze').on('click', function (evt) {
if ($('#YourformId').valid()) {
//Perform AJAX call
}
This way if any of the validations do not work, the form.valid() will throw the data annotation errors. So you can add Required to those fields in the models and it will ensure data is not sent if validation fails.
Upvotes: 3
Reputation: 326
You should stringify the JavaScript Object in the Jquery post
JSON.stringify(data)
Upvotes: 0