I've got a jqGrid setup to post to a URL using the content type of application/json:
$("#jqCategoryGrid").jqGrid({
datatype: "json",
mtype: 'POST',
url: "Webservices/TroubleTicketCategory.asmx/getCategoryData",
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
// **UPDATE - This is the fix, as per Oleg's response**
serializeGridData: function (postData) {
if (postData.searchField === undefined) postData.searchField = null;
if (postData.searchString === undefined) postData.searchString = null;
if (postData.searchOper === undefined) postData.searchOper = null;
//if (postData.filters === undefined) postData.filters = null;
return JSON.stringify(postData);
},
});
The problem is that the jqGrid is still trying to pass parameters using a non-json format so I'm getting an error "Invalid JSON Primitive"
Is there a way to instruct the jqGrid to serialize the data using Json?
Thanks
UPDATE
I edited the provided source code in my question to include the fix I used, which came from Oleg's response below.
You should include JSON serialization of the posted data for example with respect of json2.js which can be downloaded from http://www.json.org/js.html:
serializeRowData: function (data) { return JSON.stringify(data); }
Related
We use a rest api to get customer information. A lot of the GET request were already written by others. I was able to follow their code to create other GET request, but one of the API methods for updating a customer requires using json patch. Below I have pasted in sample code of a current GET method, a Patch method (that I don't know how to implement) and a sample function written in javascript on how to use the json-patch that came from the api creators demo documentation:
public GetCustomerResponse GetCustomerInfo(CustomerRequest request)
{
//All of this works fine the base url and token info is handled elsewhere
var restRequest = CreateRestRequest($"customer/account?id={request.id}", RestSharp.Method.GET);
var response = CreateRestClient().Execute<GetCustomerResponse>(restRequest);
if (response.StatusCode == HttpStatusCode.OK)
{
return response.Data;
}
else
{
return new GetCustomerResponse(response.Content);
}
}
public EditCustomerResponse EditCustomer(EditCustomerRequest request)
{
var restRequest = CreateRestRequest($"customer/account?id={request.id}", RestSharp.Method.PATCH);
var response = CreateRestClient().Execute<EditCustomerResponse>(restRequest);
//how do I pass along json patch data in here???
//sample json might be like:
//[{'op':'replace','path':'/FirstName','value':'John'},{'op':'replace','path':'/LastName','value':'Doe'}]
if (response.StatusCode == HttpStatusCode.OK)
{
return response.Data;
}
else
{
return new EditCustomerResponse(response.Content);
}
}
//javascript demo version that is working
function patchCustomer(acctId, patch, callback) {
var token = GetToken();
$.ajax({
method: 'PATCH',
url: BaseURI + 'customer/account?id=' + acctId,
data: JSON.stringify(patch),
timeout: 50000,
contentType: 'application/json; charset=UTF-8',
beforeSend: function (xhr) { xhr.setRequestHeader('Authorization', 'Bearer ' + token.access_token) },
}).done(function (data) {
if (typeof callback === 'function')
callback.call(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log("Request failed: " + textStatus);
console.error(errorThrown);
failureDisplay(jqXHR);
});
}
This was pretty simple. After viewing similar questions on stackoverflow, I initially was trying something like this:
var body = new
{
op = "replace",
path = "/FirstName",
value = "John"
};
restRequest.AddParameter("application/json-patch+json", body, ParameterType.RequestBody);
It would not work. To get it to work, I added a patchparameters class with op, path and value properties, and then added a list property of type patchparameters to my EditCustomerRequest class and used it like this:
restRequest.AddJsonBody(request.patchParams);
I am building an application using AngularJS and I have a login form from which I want to send JSON data as request body.
In my controller;
$scope.credentials = {userid: $scope.userid, password: $scope.password};
$scope.login = function () {
$http({
method : 'POST',
url : 'http://localhost/login.json',
data : $scope.credentials,
headers: {'Content-Type': 'application/json'}
}).success(function (data) {
// code
}).error(function (data, status, headers, config) {
$scope.status = status + ' ' + headers;
console.log($scope.status);
});
};
But when I am submitting the form POST request is not performing and I am getting a message in the console like;
0 function (name) {
"use strict";
if (!headersObj) headersObj = parseHeaders(headers);
if (name) {
return headersObj[lowercase(name)] || null;
}
return headersObj;
}
What am I doing wrong here?
If I changed the line
headers: {'Content-Type': 'application/json'}
to
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
the POST request is making. But I don't want to send it as form values instead I want to send the request as JSON.
You should encode javascript object to corresponding mime-type data in order to post data. If you are using jQuery, try to use $.param($scope.credentials) instead of just $scope.credentials.
I think the problem is that you're POSTing to http://localhost/login.json which is not any script that is able to receive POSTrequests with form data.
I can successfully make the AJAX call to my service with the following code:
var serverData = { "ZoneParent": "123" };
var request = $.ajax({
type: "POST",
url: "/./Services/Reports.svc/getZones",
contentType: "application/json",
dataType: "json",
jsonp: null,
jsonpCallback: null,
data: JSON.stringify(serverData)
});
request.done(function (msg) {
alert(JSON.stringify(msg));
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
However, when I try to implement the same call with my Kendo grid I get an error
The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml', 'Json'
for getZones. My service call work fine with DataTables, but I want to switch to Kendo potentially. I have messed with this for days to no avail. The application is not MVC. Here is my Kendo code snippet:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/./Services/Reports.svc/getZones",
dataType: "JSON",
data: { zoneParent: "123" },
type: "POST"
},
parameterMap: function (data, operation) {
return kendo.stringify(data);
}
},
schema: {
data: "d"
}
});
var grid = $("#allGrids").kendoGrid({
dataSource: dataSource,
height: 200
});
As cfeduke made similar suggestion you can try to add contentType to the read object of the transport read config just as you did in the $.ajax call.
e.g.
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/./Services/Reports.svc/getZones",
dataType: "json",
contentType: "application/json",
data: { zoneParent: "123" },
type: "POST"
},
parameterMap: function (data, operation) {
return kendo.stringify(data);
}
},
It sounds like the server's reply "Content-type" header is something other than the expected "application/json".
You can use cURL:
curl -v -H "Content-type:application/json" -H "Accept:application/json" \
http://localhost/Services/Reports.svc/getZones
to invoke the endpoint and check the returned header values (-v is verbose, you won't see the headers without it).
Sometimes just setting an "Accept: application/json" header is enough to reveal the problem - either the server coerces the output into JSON or it throws an error that can be tracked down.
I am investigating if there is a another way around this. But seems like Kendo has many limitations and this is one of them. Datables doesn't need a header, just the JSON format.
This is what you need to add to your controller that is sending the data (in case its ajax call)
header("Content-type: application/json");
I wish it wouldn't be like this but Kendo forces this I believe. I prefer datatables, much more freedom and you can customize more.
I have passed some JSON to my page via a webservice. I used JSON.NET to convert XML to JSON. The JSON output looks ok to me, but I am unable to access some of the items in the response. I am not sure why it is not working. I am using jQuery to read the response and make the webservice call. Even when I try to read the length of the array it says 'undefined'
function GetFeed(){
document.getElementById("marq").innerHTML = '';
$.ajax({
type: "POST",
url: "ticker.asmx/GetStockTicker",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
var obj = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
for (var i = 0; i < obj.length; i++) {
$('#marq').html(obj[i].person);
}
}
});
}
This is a copy and paste of my response as it appeared in firebug:
{"d":"{\"?xml\":{\"#version\":\"1.0\",\"#standalone\":\"no\"},\"root\":{\"person\":[{\"#id\":\"1\",\"name\":\"Alan\",\"url\":\"http://www.google.com\"},{\"#id\":\"2\",\"name\":\"Louis\",\"url\":\"http://www.yahoo.com\"}]}}"}
You should be able to read response without calling the ternary operator... anyway if you're trying to iterate over the persons array you should target response.d.root.person object, and not it's parent:
for (var i = 0; i < response.d.root.person.length; i++) {
$('#marq').html(d.root.person[i].name //.url, ...);
}
I know that Jquery's Ajax complete had issue that it's always get called twice when request complete. I'm not sure if that's the case for success.
I have an ASP.NET application in which i want to post data using jQuery to another page. It means i want post the data of page.
How can i do this with jQuery or AJAX?
Please help me.
$(document).ready(function() {
alert("start");
$("#btnSave").click(function() {
alert("start1");
var aa = 'bb';
var json = "{'ItemName':'" + aa + "'}";
alert("start2");
var ajaxPage = "Default3.aspx?Save=1"; //this page is where data is to be retrieved and processed
alert("start3");
var options = {
type: "POST",
url: ajaxPage,
data: json,
contentType: "application/json;charset=utf-8",
dataType: "json",
async: false,
success: function(response) {
alert("success: " + response);
},
error: function(msg) { alert("failed: " + msg); }
};
alert("start4");
});
});
I am using this code I am getting all alert response but its posting page.
Jquery and JSON works great with ASP.NET. You can call a code behind method directly from javascript and return complex objects, not just string. (for this example to work you need json2.js found here https://github.com/douglascrockford/JSON-js)
//javascript
function postMethod(text){
var jsonText = JSON.stringify({ name:text });
$.ajax({
type: "POST",
url: "yourpage.aspx/GetPerson",
contentType: "application/json; charset=utf-8",
data: jsonText,
dataType: "json",
success: function(response) {
var person = response.d;
alert(person.Name);
}
});
}
//aspx code behind
[WebMethod]
public static Person GetPerson(string name)
{
Person person = new Person(name);
return person;
}
There is load function.
You may use it like this:
$('#somediv').load('http://someaddress',{key:value}, function callback(){});
Second parameter is important - only written in this way performs post.(if you pass array then it performs get)
PS> This is good when you want to read the data, if you want to just do the POST and don't care about what comes back then you may want to use:
http://docs.jquery.com/Ajax/jQuery.post#urldatacallbacktype
Look at $.post() - http://docs.jquery.com/Ajax/jQuery.post
Add all your relevant data, and post away, handling the response with the supplied callback method.
There is a post function in jQuery:
$.post("test.php", { name: "John", time: "2pm" } );
This is copied directly from the jQuery API, so for more details and examples you can look there.
jQuery api
choose Ajax > Ajax Requests > $.post