AJAX call to a WebMethod - c#

I have the following Webmethod in my C#/.NET web-application, file lite_host.aspx.cs:
[WebMethod]
public static bool UpdatePage(string accessCode, string newURL)
{
bool result = true;
try {
HttpContext.Current.Cache[accessCode] = newURL;
}
catch {
result = false;
}
return result;
}
It should get the values of "accessCode" and "newURL" from a JavaScript function via a jQuery AJAX call with and make the appropriate changes in Cache:
function sendUpdate() {
var code = jsGetQueryString("code");
var url = $("#url_field").val();
var options = { error: function(msg) { alert(msg.d); },
type: "POST", url: "lite_host.aspx/UpdatePage",
data: {'accessCode': code, 'newURL': url},
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function(response) { var results = response.d; } };
$.ajax(options);
}
However when I call the sendUpdate() function, I my script ends on $.ajax error and I'm getting an alert text "undefined".

Undefined means that msg.d doesn't exist. Try doing a console.log(msg) and use Chrome's debugger to see what is outputted (yeah, I know) to the console.

Related

.NET (ApiController) / jQuery .ajax : what to return from POST?

In a Post method within a Controller derived from ApiController what should I return to indicate success to jQuery ?
I've tried HttpResponseMessage but jQuery sees this as an error (even though the argument the jQuery error handler clearly has a 200 status).
The jQuery looks like this :
processParticipantEvent: function(parID, evtType, evtNotes, successFunction, errorFunction){
debugger;
var requestURL = '/api/participantevent';
var json = {"parId" : parID, "evtType": evtType, "evtNotes": evtNotes};
var jsonArray=JSON.stringify(json);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: requestURL,
data: jsonArray ,
dataType: "json",
success: function (data) { successFunction(data); },
error: function (data) { errorFunction(data); }
});
},
I've read this : Ajax request returns 200 OK, but an error event is fired instead of success which seems like it's touching on the same issue but I suspect it's out of data as it won't work for me ?
Just to be clear all I want to do is to return a plain old 2xx with no data.
As per the documentation:
"json": Evaluates the response as JSON and returns a JavaScript
object. Cross-domain "json" requests are converted to "jsonp" unless
the request includes jsonp: false in its request options. The JSON
data is parsed in a strict manner; any malformed JSON is rejected and
a parse error is thrown. As of jQuery 1.9, an empty response is also
rejected; the server should return a response of null or {} instead.
So if you want to use jQuery ajax you have to return a valid json string, just use the following in your API controller:
return Ok(new {});
Note this is a jQuery ajax "feature", using Angular for example to do an ajax post I can use return Ok(); inside my controller and everything works as expected.
As mentioned by #Beyers the return with OK() just works.
I've created the same structure here and worked.
My Controller has this:
[Route("api/participantevent")]
public IHttpActionResult Test()
{
return Ok("");
}
And at client I've changed your function just to simplify:
processParticipantEvent= function(){
debugger;
var requestURL = '/api/participantevent';
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: requestURL,
data: [{'test': '1'}] ,
dataType: "json",
success: function (data) { alert('success'); },
error: function (data) { alert('error'); }
});
}
Your error is with the requestURL. Its value is absolute and http://api/participantevent does not exist. Try using a relative value.
var requestURL = './api/participantevent';
It seems that if you get an OK response, It is probably not a valid JSON.
I would recommend to you to check the HTTP response in the browser and try to run the JSON.parse function with the responseText and see whether it fails.
I usually declare a class like below:
public class AjaxResult
{
private bool success = true;
private List<string> messages;
public bool Success { get { return success; } set { success = value; } }
public List<string> Messages { get { return messages; } }
public AjaxResult()
{
messages = new List<string>();
}
}
In the controller, the action(to which the ajax request is made) should have JsonResult as return type.
[HttpPost]
public JsonResult Action(string id)
{
AjaxResult result = new AjaxResult();
//Set the properties of result here...
result.Success = true;
result.messages.Add("Success");
return Json(result);
}
3.And your ajax call will look like this:
$.ajax({
type: "POST",
dataType: 'json',
url: /ControllerName/Action,
data: { id: "Test"},
success: function (data) { alert('success'); },
error: function (data) { alert('error'); }
});

Object obect error on jquery ajax request on dropdown change?

I'm using jquery ajax on dropdown change function.The problem is that even before hitting the url mentioned in the ajax request I'm getting Object object error.
The ajax request is as follows
$("#locationList").change(function () {
var locationNo = document.getElementById('<%=locationList.ClientID%>').value;
$.ajax({
url: "HealthReport.aspx/GetCashsafes",
data: "{ 'Location': '" + locationNo + "'}",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
alert("Success");
response($.each(data.d, function (key, value) {
$("#CashSafeList").append($("<option></option>").val(value.CashsafeId).html(value.CashsafeDisplaySerialNo));
}));
},
error: function (result) {
alert(result);
$("#CashSafeList").append($("<option></option>").val("-1").html("Select one"));
}
});
});
The server side code is as follows
[WebMethod]
public static string GetCashsafes(string Location)
{
Decimal userId = (Decimal)AMSECSessionData.userId;
List<Cashsafe> lstCashSafe = DropDown.getCashSafeListLocationwise(userId, Convert.ToDecimal(Location));
List<CashSafeSelect> lstCashSafeSelect = new List<CashSafeSelect>();
lstCashSafeSelect = lstCashSafe.Select(item => new CashSafeSelect()
{
CashsafeId=(decimal)item.CashsafeId,
CashsafeSerialNo=item.CashsafeSerialNo.ToString()
}).Distinct().ToList();
System.Web.Script.Serialization.JavaScriptSerializer jSearializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
string sjson=jSearializer.Serialize(lstCashSafeSelect);
return sjson;
}
I've checked the string sjson and the data is returning correctly in json format.
Since the error is showing even before the url is hit,i'm confused on how to proceed further.
Any help will be appreciated.
Change the data like this
data: JSON.stringify({ 'Location': locationNo }),
Then your code will look like
$("#locationList").change(function () {
var locationNo = document.getElementById('<%=locationList.ClientID%>').value;
$.ajax({
url: "HealthReport.aspx/GetCashsafes",
data: JSON.stringify({ 'Location': locationNo }),
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
alert("Success");
response($.each(data.d, function (key, value) {
$("#CashSafeList").append($("<option></option>").val(value.CashsafeId).html(value.CashsafeDisplaySerialNo));
}));
},
error: function (result) {
alert(result);
$("#CashSafeList").append($("<option></option>").val("-1").html("Select one"));
}
});
});
Edit
Since your dataType is json, you should return json, not string. Change your server side code like this,
[WebMethod]
public static List<CashSafeSelect> GetCashsafes(string Location)
{
Decimal userId = (Decimal)AMSECSessionData.userId;
List<Cashsafe> lstCashSafe = DropDown.getCashSafeListLocationwise(userId, Convert.ToDecimal(Location));
List<CashSafeSelect> lstCashSafeSelect = new List<CashSafeSelect>();
lstCashSafeSelect = lstCashSafe.Select(item => new CashSafeSelect()
{
CashsafeId=(decimal)item.CashsafeId,
CashsafeSerialNo=item.CashsafeSerialNo.ToString()
}).Distinct().ToList();
return lstCashSafeSelect;
}
You dont have to serialize those lists
Issue solved,Thanks to every one who replied especially #Anoop.
Issue was that I've set Autopostback=true for the dropdown where the ajax call is made.I've removed the autopostback property of the dropdown and now the code is working fine.
I wonder how a fresh day,clear mind helps to solve the issues.

.JQuery .ajax how do I call WCF method with return value?

I have been able to call WCF methods with .ajax. How do I call a method that returns a value? I need to call this method to see if data is ready and if not wait one second. The WCF method is:
[OperationContract]
[WebGet]
public bool IsDataReady(string requestGUID)
{
if (Global.publicDataDictionary.Keys.Contains(requestGUID))
return true;
else return false;
}
My JavaScript so far is:
$(document).ready(function() {
var input = {requestGUID:"<%=guid %>"};
console.log(input);
$.ajax({
url: "http://www.blah.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
dataType: "json",
success: function(data) {
}
});
EDIT2: I broke out the 2nd ajax call into a method but my logging is showing that the call to 2nd web service never passes a requestGUID. Can't i use the same input variable?
var guid = "<%= this.guid%>";
// var input = '{"SbiId":"' + guid + '"}';
// var input = {requestGUID:"ca222cf7-be5e-431a-ab93-9a31e8ae2f4a"};
function callUpdateGrid(input) {
console.log(input);
$.ajax({
url: "http://www.blah.com/services/TestsService.svc/GetContactsDataAndCountbyGUID",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
dataType: "json",
success: function (data) {
var mtv = $find("<%= RadGrid1.ClientID %>").get_masterTableView();
console.log(data);
mtv.set_dataSource(data.d.Data);
mtv.dataBind();
}
});
}
function CallIsDataReady(input) {
$.ajax({
url: "http://www.blah.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
dataType: "json",
success: function (data) {
if (!data) {
setTimeout(function (inputInner) { CallIsDataReady(inputInner); }, 1000);
}
else {
//Continue as data is ready
callUpdateGrid(input);
}
}
});
}
$(document).ready(function () {
var input = { requestGUID: "<%=guid %>" };
CallIsDataReady(input);
});
EDIT2: I broke out the 2nd ajax call into a method but my logging is showing that the call to 2nd web service is never getting called:
url: "http://www.blah.com/services/TestsService.svc/GetContactsDataAndCountbyGUID",
else {
//Continue as data is ready
callUpdateGrid(input);
}
The return value will be contained in the data parameter passed to the success callback setup in your ajax call.
You will need to check the value here, then if false, setup a timeout, which on expiry will attempt the ajax call again.
It would be best IMO to wrap up the Ajax call inside a function, that you can call in a recursive fashion when the timeout has expired. e.g.
function CallIsDataReady(input){
$.ajax({
url: "http://www.blah.com/services/TestsService.svc/IsDataReady",
type: "GET",
contentType: "application/json; charset=utf-8",
data: input,
dataType: "json",
success: function(data) {
if (!data){
setTimeout(function(){CallIsDataReady(input);}, 1000);
}
else{
//Continue as data is ready
}
}
});
}
$(document).ready(function() {
var input = {requestGUID:"<%=guid %>"};
console.log(input);
CallIsDataReady(input);
});
When you view source on this page is:
var input = {requestGUID:"<%=guid %>"};
showing correctly in the javascript? If you put a breakpoint in your IsDataReady method, do you see if requestGUID has a value? Is your service on the same domain as the page calling it?
EDIT:
In your service change: [WebGet]
to:
[WebGet(
RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json]
Read up on RESTful web services:
http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide

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.

JSON stringify to C# Webservice

I know there are a few questions out there but I've tried a lot of them and I'm still not able to even get my script to make it to the server. Here is what I currently have:
Javascript
function UpdateSessionUser(user)
{
if (user != null)
{
var targetPage = "http://" + document.location.host + "/Sitefinity/Services/Sandbox/SessionUsers.asmx/UpdateSessionUser";
var dataText = { "jsonUser" : JSON.stringify(user) };
try
{
$.ajax({
type: "POST",
url: targetPage,
data: dataText,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response)
{
alert(response.d);
return true;
},
failure: function (msg)
{
alert(msg);
return false;
}
});
}
catch (err)
{
alert(err);
}
}
}
Example of user object
Object
BaseID: "fe85149c-71f2-4c61-b7c6-a00300e2f84e"
HasChanged: true
IsReferralReceived: false
IsReferralRequired: true
IsSeatApproved: true
Name: "Miles"
ReferralFromUser: null
ReferralFromUserID: null
ReferralReceivedBy: null
ReferralReceivedByUserID: null
ReferralReceivedOn: "/Date(-62135578800000)/"
RegisteredOn: "1330281960000"
SeatApprovedBy: null
SeatApprovedByUserID: null
SeatApprovedOn: "/Date(-62135578800000)/"
SeatNumber: "2"
SessionID: "d0773d5e-aeeb-4b9c-b606-0a564d6c5845"
UserID: "6af2fd9e-b4b6-4f5a-8e9c-fe7ec154d4e5"
__type: "SandboxClassRegistration.SessionUserField.ClientSessionUser"
C#
[WebMethod]
public bool UpdateSessionUser(object jsonUser)
{
return SessionUserHelper.UpdateSessionUser(new ClientSessionUser(jsonUser));
}
Why does my JSON call never make it to the server? I've put a break point at the very beginning of the function (before the return) just so I can look at the jsonUser object parameter but it never makes it there.
All I get in return is this error:
POST http://localhost:60877/Sitefinity/Services/Sandbox/SessionUsers.asmx/UpdateSessionUser 500 (Internal Server Error)
--- UPDATE
Here is the final result (I had to "stringify" the object and then the final dataText being sent). The webservice method was unchanged
function CallWebServiceToUpdateSessionUser(target, user)
{
var dataText = { "jsonUser": JSON.stringify(user) };
$.ajax({
type: "POST",
url: target,
data: JSON.stringify(dataText),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response)
{
alert(response.d);
return true;
},
failure: function (msg)
{
alert(msg);
return false;
}
});
}
I don't how much would help:
try change this
var dataText = { "jsonUser" : JSON.stringify(user) };
to
var dataText = JSON.stringify({ "jsonUser" : user });
I think you need to mark your service method as JASON enabled.
[WebMethod]
[ScriptMethod(UseHttpGet = true,ResponseFormat = ResponseFormat.Json)]
public bool UpdateSessionUser(object jsonUser)
{
return SessionUserHelper.UpdateSessionUser(new ClientSessionUser(jsonUser));
}
I realize this question was answered a while ago, but I had similar problem, and would like to provide some details on why OP's solution works
I assume the web service expects a string, which it will Deserialize and work with
In this case, calling JSON.stringify({"jsonUser": user}) does not convert user object to string, which will cause problems on the server.
When you call JSON.stringify({"jsonUser": JSON.stringify(user)}), your user oblect is converted to string with all quotes properly escaped.
Hope this helps someone in the future.
Here's the fiddle to illustrate http://jsfiddle.net/dvwCg/2/ :
HTML
<h1>webservice breaks</h1>
<span id="s1"></span>
<h1>webservice works</h1>
<span id="s2"></span>
JS
var jsonObject = {"a":1, "b":[{"x":"test", "y":12}, {"x":"test2", "y":120}]};
$("#s1").text(JSON.stringify({"d" : jsonObject}));
$("#s2").text(JSON.stringify({"d" : JSON.stringify(jsonObject)}));
p.s.
https://stackoverflow.com/a/6323528/3661 has a lot of useful info as well.

Categories