Error: Undefined object! while parsing JSON using jquery - c#

This should be simple but I cannot seem to get this to work correctly.
Given a JSON string that looks like this:
{
"?xml":
{
"#version":"1.0",
"#encoding":"ISO-8859-1"
},
"results":
{
"title":"AOL Movies - Closest Theater and Showtimes",
// etc,
"theater":
{
"theaterId":"10650",
"id":"10650",
// etc
},
"movie":
[
{
"studios":"Warner Bros.",
"movieId":"61683"
}
]
}
I continually get undefined objects when trying to get to any value, for example:
data.movie, or data.results.title.
Everything "looks" ok in the output.
jQuery.ajax({
type: 'GET',
contentType: 'application/json',
url: 'handler.ashx',
data: 'zip=' + postalCodes.join(','),
success: function (payload) {
var data = that.objectifyJSON(payload); // this returns typeof = object
that.constructMoviesArray(data);
},
error: function (error) {
alert(error.responseText);
}
});
this.constructMoviesArray = function (data) {
var key, movie, theater = null;
var movies = {};
movies.items = {};
movies.length = 0;
alert(data[0].movie); // FAIL - there's clearly an array but nothing displays
I hope this is enough information; I am not experienced with JSON and jQuery so I'm struggling to figure out why I can't seem to resolve this.

Add the json dataType. http://api.jquery.com/jquery.ajax/
The server response is probably still a string even though you set the contentType.
jQuery.ajax({
type: 'GET',
contentType: 'application/json',
url: 'handler.ashx',
data: 'zip=' + postalCodes.join(','),
dataType: 'json', // <--- UPDATE ME
success: function (payload) {
var data = that.objectifyJSON(payload); // this returns typeof = object
that.constructMoviesArray(data);
},
error: function (error) {
alert(error.responseText);
}
});
If that doesn't help, try adding a console.log or a breakpoint to the success callback. You'll be able to take a closer look at what kind of data you are working with in payload.
success: function (payload) {
console.log(payload);
},
Hope that helps!

Try Like
var geocodingAPI = "http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true";
$.getJSON(geocodingAPI, function (json) {
// Set the variables from the results array
var address = json.results[0].formatted_address;
console.log('Address : ', address);
var latitude = json.results[0].geometry.location.lat;
console.log('Latitude : ', latitude);
var longitude = json.results[0].geometry.location.lng;
console.log('Longitude : ', longitude);
// Set the table td text
$('#address').text(address);
$('#latitude').text(latitude);
$('#longitude').text(longitude);
});
Demo

Related

Passing array from view to controller using Ajax but, on action, array shows as empty

I am passing an array from view to controller using Ajax but, on action, the array shows empty.
This is my code:
View
$("#btn").click(function () {
debugger
arry = [];
$.ajax({
type: "Post",
url: "/Main/CheckBoxes",
data: { Values: arr["48","47","46"] },
success: function () {
alert("array: " + arry.join(', '));
},
error: function () {
alert("error");
}
})
});
Action
public ActionResult array(string[] Values)
{
for (int id = 0; id < Values.Length; id++)
{
string newID = Values[id];
}
return View();
}
jQuery.ajaxSettings.traditional = true;
$("#btn").click(function () {
debugger
arry = [];
$.ajax({
type: "Post",
url: "/Main/CheckBoxes",
data: { Values:["48","47","46"]},//just edit this line
success: function () {
alert("array: " + arry.join(', '));
},
error: function () {
alert("error");
}
})
});
Your code has some issues regarding how you are sending the data! What is your expectation when you execute this expression arr["48","47","46"] ????? That is going to give you undefined and that is what you are trying to send!
There are two ways to fix your code. You can send the array in the request body. For this, you need create a JSON string from the array and send that as the data property while explicitly specifying the request content-type header value as "application/json". You may use the JSON.stringify method to get the JSON string of your js array.
Also, make sure you are making the call to the correct action method. In your question you shared the array action method code, but in your client side script you were trying to call a different action method(`Checkboxes)!
This should work.
var arry = ["48", "47", "46"];
var url = "#Url.Action("array", "Main")"; // Update your real url here
// If your script is inside the razor view, you can us Url.Action (c#) method
$.ajax({
type: "Post",
url: url ,
data: JSON.stringify(arry),
contentType: "application/json",
success: function(r) {
alert("Success");
console.log(r);
},
error: function() {
alert("error");
}
});
Another option is to send a javascript object with Values property (which has the array as the value of it) as the data property value of the $.ajax call. Now the request content-type header will be application/x-www-form-urlencoded; and the array will be sent as FormData in the request.
var arry = ["48", "47", "46"];
$.ajax({
type: "Post",
url: "/Main/array",
data: { Values: arry },
success: function(r) {
console.log(r);
},
error: function() {
alert("error");
}
});

Map Json data to an object using AJAX and C#

how can I use the Json formatted data sent by an AJAX request in C#?
Here's the View with the JQuery and AJAX
<script type="text/javascript">
$(function () {
$("#btnGet").click(function () {
var values =
{
"Name": "Manuel Andrade",
"DateOfBirth": "12/01/1995"
}
$.ajax({
type: "POST",
url: "/api/WebApi/GetAge",
data: values,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("Hello: " + response.Name + ".\nCurrent Date and Time: " + response.DateTime);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
</script>
Here's the Controller:
public class PersonController : ApiController
{
[System.Web.Http.Route("api/WebApi/GetAge")]
[System.Web.Http.HttpPost]
public Person GetAge(Person person)
{
//person = new Person();
//person.Name = "Luis";
JsonTest(person);
//int ageInMonths = calculateAgeInMonths(person);
//int ageInYears = calculateAgeInYears(person);
//System.Diagnostics.Debug.WriteLine(ageInMonths);
//System.Diagnostics.Debug.WriteLine(ageInYears);
return person;
}
}
The Person Model has exactly the same attributes as the Json variable in the view. Shouldn't it create an object automatically? The method JsonTest() works properly, it is used to serialize the data. If I uncomment the person instantiation and assignation to Luis the method does return a Json with that data to the view. But if I try to use the person parameter just like that it throws a null Exception. How can I pass the var values in the View to the GetAge method so I can assign it to an object?
It worked fine for me when I removed the contentType: "application/json; charset=utf-8", line.
It isn't returned as application/json by default.

How to remove current row from a html table in jQuery json?

I want to write code for multipledelete by using jquery json.
This is the jquery code:
function DeleteSelected() {
var categories = new Array();
debugger;
// iterate all checkboxes and obtain their checked values, unchecked values are not pushed into array
$("input[type='checkbox']").each(function ()
//$('input[type=checkbox]').prop("checked", this.checked)
{
this.checked ? categories.push($(this).val()) : null;
});
// assume urldata is your web method to delete multiple records
var urldata = "WebForm5.aspx/deleteRecord";
debugger;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: urldata,
data: "{ 'Id':'"+JSON.stringify( categories)+"' }", // used to convert array into proper JSON format
dataType: "json",
success: function (dt) {
// done whatever tasks if succeeded
alert("entry deleted");
debugger;
$("#example1").DataTable();
//$("#example1").bind;
debugger;
},
error: function (result) {
alert("Error");
}
});
}
This is aspx code(codebehind for multiple delete):
[WebMethod]
// note clear difference between single and multiple selections
public static void deleteRecord(List<int> Id)
{
clsCategoryBL objproject = new clsCategoryBL();
// iterate through input list and pass to process method
for (int i = 0; i < Id.Count; i++)
{
objproject.CategoryDelete(Id[i]);
}
}
I want to pass the id to aspx page but the problem is that output comes error popup.
error: function (result) {
alert("Error");
}
The below line will return JSON for the array categories
"{ 'Id':'"+JSON.stringify( categories)+"' }"
Validate the value with http://jsonlint.com/ and check if the result is valid JSON.
Since you had declared the method as public static void deleteRecord(List<int> Id) that means the expected input will be like [1,2,3]
Also use below line to get exact error coming
error: function (xhr, ajaxOptions, thrownError) {
alert("error # " + xhr + ajaxOptions + thrownError);
}
UPDATE 1:
Below is working code
var categories = new Array();
// do your logic to push
categories.push(1);
categories.push(2);
categories.push(3);
var valuetxt = "{ \"Id\":\"" + JSON.stringify(categories) + "\" }";
var urldata = "WebForm1.aspx/deleteRecord";
$.ajax({
type: "POST",
url: urldata,
data: valuetxt, // used to convert array into proper JSON format
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
// in result you will get same data which is posted
alert(result.d);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("error # " + xhr + ajaxOptions + thrownError);
}
});
[WebMethod]
// change the parameter to string, convert back JSON to Integer Array
public static string deleteRecord(string Id)
{
// do something - for sample here returning same JSON of integer
return Id;
}

Iterate returned c# serialized List<string> in jQuery

I have a webmethod which will read the first line in a csv file to get the column titles then store each item in the list which I will return to the ajax call. This is the code:
[WebMethod]
public static string getAvailableSensors()
{
List<string> sensors = new List<string>();
try
{
string path = "C:\\.....\\TestData3.csv";
string line;
using (StreamReader sr = new StreamReader(path))
{
line = sr.ReadLine();
sensors = line.Split(',').ToList();
}
}
catch (Exception ex)
{
string error = ex.Message;
}
JavaScriptSerializer jss = new JavaScriptSerializer();
string output = jss.Serialize(sensors);
return output;
}
This is what the data looks like when it is returned to the ajax call:
This is what my ajax looks like :
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebSockets.aspx/getAvailableSensors",
async: false,
data: "{ }", // send an empty object for calls with no parameters
success: function (result) {
debugger;
data = result.d;
for (var i in result.d) {
sensors.push(result.d[i]);
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert("an error has occured: " + xhr.responseText);
}
});
but this only populates the array 1 character at a time which is not what I am trying to do.
I cannot figure out how to iterate the damn json so that I can populate my var sensors = new Array(); with the columns. ex( sensor[0] should be "Time", sensor[ 1 ] should be "X Accel LH" ) etc.
First of all you need to make that string as an object. Use jQuery.parseJSON() to make it as object.
data=jQuery.parseJSON(data);
In your case, you can use the data like a string array
In your AJAX options you should set dataType: 'json' so that the response is automatically converted to JSON before being handed to your callback. This is probably what you expected the contentType to do, but in reality that sets the type of the content being sent, not what you expect to be returned. You might also want to apply a ScriptMethodAttribute and specify the result being returned is JSON - I believe this will set the Content-Type header so that jQuery can automatically detect the format in the absence of specifying it in your options.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string getAvailableSensors()
{
...
}
JavaScript
$.ajax({
type: "POST",
dataType: "json", // <-- this
contentType: "application/json; charset=utf-8",
url: "WebSockets.aspx/getAvailableSensors",
async: false,
data: "{ }", // send an empty object for calls with no parameters
success: function (result) {
debugger;
data = result.d;
for (var i in result.d) {
sensors.push(result.d[i]);
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert("an error has occured: " + xhr.responseText);
}
});
If you're using a newer version of jQuery you might want to look into replacing your success and error callbacks with the done and fail methods.
$.ajax({
type: "POST",
dataType: "json", // <-- this
contentType: "application/json; charset=utf-8",
url: "WebSockets.aspx/getAvailableSensors",
async: false,
data: "{ }", // send an empty object for calls with no parameters
})
.done(function(result) {
debugger;
data = result.d;
for (var i in result.d) {
sensors.push(result.d[i]);
}
})
.fail(function(xhr, status, error) {
alert("an error has occured: " + xhr.responseText);
});
You could just return an IList<string> from your web method instead of serializing manually.
[WebMethod]
public static IList<string> getAvailableSensors()
{
List<string> sensors = new List<string>();
string path = "C:\\.....\\TestData3.csv";
string line;
using (StreamReader sr = new StreamReader(path))
{
line = sr.ReadLine();
sensors = line.Split(',').ToList();
}
return sensors;
}
Also, your error handling is not exaclty correct. For the client, the operation succeeded even if there is an error on server side. I just removed you try catch to let the exception propagate to the client.

Complex type is getting null in a ApiController parameter

I don´t know why my parameter "ParametroFiltro Filtro" is getting null, the other parameters "page" and "pageSize" is getting OK.
public class ParametroFiltro
{
public string Codigo { get; set; }
public string Descricao { get; set; }
}
My ApiController Get method:
public PagedDataModel<ParametroDTO> Get(ParametroFiltro Filtro, int page, int pageSize)
My ajax call:
var fullUrl = "/api/" + self.Api;
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Filtro: { Codigo: '_1', Descricao: 'TESTE' }, page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
You are trying to send a complex object with GET method. The reason this is failing is that GET method can't have a body and all the values are being encoded into the URL. You can make this work by using [FromUri], but first you need to change your client side code:
$.ajax({
url: fullUrl,
type: 'GET',
dataType: 'json',
data: { Codigo: '_1', Descricao: 'TESTE', page: 1, pageSize: 10 },
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
This way [FromUri] will be able to pick up your complex object properties directly from the URL if you change your action method like this:
public PagedDataModel<ParametroDTO> Get([FromUri]ParametroFiltro Filtro, int page, int pageSize)
Your previous approach would rather work with POST method which can have a body (but you would still need to use JSON.stringify() to format body as JSON).
Provide the contentType property when you make the ajax call. Use JSON.stringify method to build the JSON data to post. change the type to POST and MVC Model binding will bind the posted data to your class object.
var filter = { "Filtro": { "Codigo": "_1", "Descricao": "TESTE" },
"page": "1", "pageSize": "10" };
$.ajax({
url: fullUrl,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(filter),
success: function (result) {
alert(result.Data.length);
self.Parametros(result.Data);
}
});
It's also possible to access POST variables via a Newtonsoft.Json.Linq JObject.
For example, this POST:
$.ajax({
type: 'POST',
url: 'URL',
data: { 'Note': note, 'Story': story },
dataType: 'text',
success: function (data) { }
});
Can be accessed in an APIController like so:
public void Update([FromBody]JObject data)
{
var Note = (String)data["Note"];
var Story = (String)data["Story"];
}
If you append json data to query string, and parse it later in web api side. you can parse complex object too. It's useful rather than post json object, espeicaly in some special httpget requirement case.
//javascript file
var data = { UserID: "10", UserName: "Long", AppInstanceID: "100", ProcessGUID: "BF1CC2EB-D9BD-45FD-BF87-939DD8FF9071" };
var request = JSON.stringify(data);
request = encodeURIComponent(request);
doAjaxGet("/ProductWebApi/api/Workflow/StartProcess?data=", request, function (result) {
window.console.log(result);
});
//webapi file:
[HttpGet]
public ResponseResult StartProcess()
{
dynamic queryJson = ParseHttpGetJson(Request.RequestUri.Query);
int appInstanceID = int.Parse(queryJson.AppInstanceID.Value);
Guid processGUID = Guid.Parse(queryJson.ProcessGUID.Value);
int userID = int.Parse(queryJson.UserID.Value);
string userName = queryJson.UserName.Value;
}
//utility function:
public static dynamic ParseHttpGetJson(string query)
{
if (!string.IsNullOrEmpty(query))
{
try
{
var json = query.Substring(7, query.Length - 7); //seperate ?data= characters
json = System.Web.HttpUtility.UrlDecode(json);
dynamic queryJson = JsonConvert.DeserializeObject<dynamic>(json);
return queryJson;
}
catch (System.Exception e)
{
throw new ApplicationException("can't deserialize object as wrong string content!", e);
}
}
else
{
return null;
}
}
In .NET Core, the HttpClient sets the transfer-encoding: chunked header by default. This can cause the .NET Web API controller parameters to be null.
To get around this, you'll need to set the ContentLength header explicitly:
var json = JsonConvert.SerializeObject(myObject);
var content = new StringContent(json, Encoding.UTF8, "application/json");
content.Headers.ContentLength = json.Length;
var response = await client.PostAsync("http://my-api.com", content);
SO answer if you already know the transfer-encoding header is the issue: How to disable Chunked Transfer Encoding in ASP.Net C# using HttpClient
Related bug which won't be fixed, which gives some insight into the problem: https://github.com/dotnet/runtime/issues/30283

Categories