I am learning about POST with Ajax and I've noticed a lot of examples using stringify on static arrays.
In my example I am building array via jQuery objects extracted from <input> values.
Jquery
function PostEdit(vData){
var content = JSON.stringify(vData); //content = "[{"Id":"1","Date":"7/12/2017 12:00:00 AM"}]"
$.ajax({
url: '#Url.Action("Index", "PostViewData")',
type: "POST",
data: JSON.stringify({ ViewData : vData }),
contentType: "application/json",
success: function (result) {
alert("success" + result);
},
error: function (result) {
alert("failure" + result);
}
});
return;
}
Controller
[HttpPost]
public ActionResult Index(List<DataViewModel> ViewData )
{
if(ViewData != null)
{
var json = new { success = true };
return Json(json);
}
return Json(false);
}
ViewModel
public class DataViewModel
{
public DataViewModel(string id, string date)
{
Id = id;
Date = date;
}
public string Id { get; set; }
public string Date { get; set; }
}
Where DataViewModel is a class that consists of two values, Id, and Date which correspond to my JS object.
Since vData enters the function as value vData = [Object], When I call .stringify(vData) it returns content = "[{"Id":"1","Date":"7/12/2017 12:00:00 AM"}]"
The value of content above is how I see most examples structured before stringify such as the example here.
Once in this format, this is when most responses, examples call stringify anyway.
Now when I call .stringify(ViewData : vData) I dont even make it to the controller. Ajax fails to post. On the contrary when I call .stringify(ViewData : content), I make it to the controller, but with a null value. What am I missing / misunderstanding?
I'm looking for a better explanation of Ajax Post and Stringify, and how it interacts with the controller parameter.
Just add parameterless constructor to your model. With that change, your code will work as it is. ASP is unable to parse your json as DataViewModel since it's trying to call default constructor that doesn't exists.
public class DataViewModel
{
public DataViewModel()
{
}
//...other methods and members here
}
Please try the solution below.
There's another way of doing this
function PostEdit(vId, vDate){
$.ajax({
url: '/PostViewData/Index' // it should be '/controller/method'
type: "POST",
data: JSON.stringify({ Id: vId, Date: vDate}),
contentType: "application/json",
success: function (result) {
alert("success" + result);
},
error: function (result) {
alert("failure" + result);
}
});
return;
}
[HttpPost]
public ActionResult Index(string Id, string Date )
{
if(Id != null)
{
var json = new { success = true };
return Json(json);
}
return Json(false);
}
Update: In the controller method, it should be string id, string date
Update: The constructor should be parameterless. From the answer mentioned below
public DataViewModel()
{
}
Related
I don't know what happened the value sent to the controller is always null, even though in the console.log the value is there, please I need help
this is my ajax:
$('#ddlItemName').change(function () {
var ItemCode = $('#ddlItemName').text();
if (ItemCode != '') {
var RequestParam = {
search: ItemCode
}
console.log(RequestParam);
$.ajax({
url: '/Order/CustomerItemOrders',
type: 'POST',
data: JSON.stringify(RequestParam),
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data[0].Name);
},
error: function (data) {
toastr.error(data);
}
});
}
$('#ddlItemName').text('');
});
This is my controller :
[HttpPost]
public JsonResult CustomerItemOrders([FromBody] string search)
{
var result = _order.BindCustomerOrders(search);
return Json(result.data);
}
This is my error :
enter image description here
I've tried adding '[FromBody]' but the value parameter still doesn't get sent
I recomend you add the parameter to query
If you insist on pass the value with request body
Try creat a model:
public class SomeModel
{
public string search{get;set;}
}
in your controller:
public JsonResult CustomerItemOrders([FromBody] SomeModel somemodel)
{
.......
}
I have this method to send some data with ajax:
function SendData(foodID, basketID) {
var data = { FoodID: foodID, BasketID: basketID };
$.ajax({
url: '/Order/Post',
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json;utf-8',
datatype: 'json'
}).done(function (data) {
console.log(data);
}).fail(function (data) {
console.log("Error: " + data);
});
}
In C#, my Post Method in my Order controller gets triggered, but the string I want to hand over is null:
public bool Post(string s)
{
//When this gets executed, s is null
return true;
}
I tested this by executing SendData(1,1) directly on a button click. What is the mistake I'm doing and how can I get the string in my Post-Method?
you are post the object. not string.
you can try generate to object and load this object. or add new one parameter to action (foodId and basketId but you must post like that if you check this option data:{foodId,basketId})
//model
public class SomeObject{
public string FoodId {get;set;}
public string BasketId {get;set;}
}
//code
public bool Post(SomeObject data)
{
return true;
}
It seems for me your data structure to the Post action doesn't match action parameter names. Try this:
[HttpPost]
public bool Post(string foodID, string baskedID)
{
return true;
}
I believe you have to name your data that's being passed like so:
data: { 's': JSON.stringify(data) }
I have this for that fills an array, where the cont came from View
function GenerateJSON(cont) {
var songs= [];
for (var i = 0; i <= cont; i++) {
songs[i] = {
id: i,
genre: $(".genre" + i).val(),
song: $(".song" + i).val()
}
}
$.ajax({
url: "Generate",
type: 'POST',
dataType: "json",
data: { songs: JSON.stringify(songs) },
success: function (data) {
}
})
}
On Controller, i got only one block music
example:
songs= [{"id":0,"genre":"","song":"","id":1,"genre":"","song":"","id":2,"genre":"","song":""}]
I want this:
songs=[{"id":0,"genre":"","song":""},{"id":1,"genre":"","song":""},{id":2,"genre":"","song":""}]
Controller
public JsonResult Generate(string[] songs)
{}
Using a string array as the parameter does not make sense to me. Now you have to make client side code to build some sophisticated string and in server side you have to parse it to get each item's property values.
IMHO, The clean approach is to use a view model and take advantage of MVC model binding. Start by creating a view model to represent your data.
public class SongVm
{
public int Id { set; get; }
public string Genre { set; get; }
public string Song { set; get; }
}
Now use this as the parameter of your action method. Since you want to send a collection of your objects, use List<SongVm> as your parameter.
[HttpPost]
public ActionResult Gerar(List<SongVm> songs)
{
// Simply returning the data with a message property as well
return Json(new { messge ="success", data = songs });
}
Now from the client side code, send the JSON string version of your array, while specifying application/json as the value of contentType property of the option we are passing to the $.ajax method.
var songs = [];
for (var i = 0; i <= cont; i++) {
songs[i] = {
id: i,
genre : "test genre" + i,
song : "test song" + i
};
}
$.ajax({
url: "/Home/Gerar",
type: 'POST',
contentType: "application/json",
data: JSON.stringify(songs),
success: function (data) {
console.log(data);
},
error: function (a, b, c) {
console.log(c);
}
})
Now $.ajax will add the request header Content-Type to the call with the value application/json. As part of model binding, the default model binder will read this request header value and then decide to read the data from the request body(Request payload)
I would also recommend leveraging the Url helper methods like Url.Action to generate the correct relative path to the action method.
mycode:
object:
public class Person
{
private string _Nome;
private DateTime _Nascimento;
public string Nome { get { return _Nome; } }
public DateTime Nascimento { get { return _Nascimento; } }
public Person(string Nome, DateTime Nascimento)
{
_Nome = Nome;
_Nascimento = Nascimento;
}
}
page (WebMethods):
[WebMethod]
public static Person SendPerson()
{
return new Person("Jhon Snow", DateTime.Now);
}
[WebMethod]
public static string ReceivePerson(Person oPerson)
{
return "OK!";
}
javascript:
var Person;
GetPerson();
SendPersonBack();
function GetPerson()
{
$.ajax({
type: "POST",
url: "frmVenda.aspx/SendPerson",
data: {},
contentType: "application/json; charset=utf-8",
success: function (RequestReturn) {
Person = RequestReturn.d;
console.log(Person);
},
error: function (error) {
alert(error.statusText);
}
});
}
function SendPersonBack()
{
$.ajax({
type: "POST",
url: "frmVenda.aspx/ReceivePerson",
data: JSON.stringify({"oPerson": Person}),
contentType: "application/json; charset=utf-8",
success: function (RequestReturn) {
alert(RequestReturn.d);
},
error: function (error) {
alert(error.statusText);
}
});
}
I send the object to the clientside normally, but can not receive it back to server.
Why can not receive it back if the object is the same and their properties as well.
where is the problem?
Looking at the very link provided by you is possible to notice the problem.
Your code: data: JSON.stringify({"oPerson": Person}),
Right code: data: "{oPerson:" + JSON.stringify(Person) + "}",
It seems to me that you're sending a bad formatted Json to the server
Also, try adding dataType: 'json' to your call.
I solved the problem by creating a constructor with no parameters , setting all properties as string and adding the set method on all properties on my custom object (Person).
public class Person
{
private string _Nome;
private string _Nascimento;
public string Nome { get { return _Nome; } set { _Nome = value; } }
public string Nascimento { get { return _Nascimento; } set { _Nascimento= value; } }
public Person()
{
}
public Person(string Nome, DateTime Nascimento)
{
_Nome = Nome;
_Nascimento = Nascimento.ToString();
}
}
You are returning an object from webService, but your content type in ajax is json! You should create data in json format in both of your methods and return a string not object:
[WebMethod]
public static static SendPerson()
{
JavaScriptSerializer TheSerializer = new JavaScriptSerializer();
return TheSerializer.Serialize(new Person("Jhon Snow", DateTime.Now));
}
For second method just remove content-type from ajax or replace it by :
application/x-www-form-urlencoded; charset=UTF-8
I know I'm missing something in the details here.
Problem
Despite Googling, trying examples, different formats, etc, the AJAX request that I send always is validated as having all fields empty, but not being null.
I think I'm not sending things in the proper format for the controller to recognize it as an object but I'm not sure what.
Fiddler: What my request looks like
With some dummy data:
Code: Model Class
public class ContactUsMessage
{
public string Email { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string Message { get; set; }
}
Code: WebAPI Controller
[HttpPost]
public HttpResponseMessage NewMessage(ContactUsMessage messageToSend)
{
if (messageToSend == null)
{
var sadResponse = Request.CreateResponse(HttpStatusCode.BadRequest, "Empty Request");
return sadResponse;
}
var messageValidator = new ContactUsMessageValidator();
var results = messageValidator.Validate(messageToSend);
var failures = results.Errors;
var sadString = "";
if (!results.IsValid)
{
foreach (var error in failures)
{
sadString += " Problem: " + error.ErrorMessage;
}
var sadResponse = Request.CreateResponse(HttpStatusCode.NotAcceptable, "Model is invalid." + sadString);
return sadResponse;
}
else
{
SendContactFormEmail(messageToSend.Email, messageToSend.Name, messageToSend.PhoneNumber, messageToSend.Message);
}
Code: JavaScript on Page
function sendSubmissionForm() {
var dataObject = JSON.stringify(
{
messageToSend: {
'Email': $('#inpEmail').val(),
'Name': $('#inpName').val(),
'PhoneNumber': $('#inpPhone').val(),
'Message': $('#inpMessage').val()
}
});
$.ajax({
url: '/api/contactus/newmessage',
type: 'POST',
done: submissionSucceeded,
fail: submissionFailed,
data: dataObject
});
}
When you JSON.stringifyied your data object you converted it to JSON. But you forgot to set the Content-Type request header and the Web API has no way of knowing whether you are sending JSON, XML or something else:
$.ajax({
url: '/api/contactus/newmessage',
type: 'POST',
contentType: 'application/json',
done: submissionSucceeded,
fail: submissionFailed,
data: dataObject
});
Also when building the JSON you don't need to wrap it in an additional property that matches your method argument name. The following should work as well:
var dataObject = JSON.stringify({
'Email': $('#inpEmail').val(),
'Name': $('#inpName').val(),
'PhoneNumber': $('#inpPhone').val(),
'Message': $('#inpMessage').val()
});