I'm having trouble with calling a WebMethod with Jquery.
function runQuery(e) {
var search = $(e).val();
var csKind;
if ($('#rbLP').is(':checked'))
csKind = 1;
else
csKind = 0;
var params = {
url: 'addEditProduct.ascx/AutoComplete_Press',
method: 'post',
contentType: 'application/json',
data: JSON.stringify(search),
dataType: 'json',
success: function(data) {
alert(1);
},
error: function(data) {
alert(2);
}
};
$.ajax(params);
}
[WebMethod]
public static void AutoComplete_Press(string searchClause, int csKind)
{
int searchType = 0; //ЕГН
Regex regex = new Regex("^[0-9]+$");
if (!regex.IsMatch(searchClause))
searchType = 1;
string clients = laboratory.getClients2(searchType, searchClause, csKind);
}
How can I diagnose the problem, I've never used ajax before and I'm at a loss.
The problem I can see here is your passing arguments:
data: JSON.stringify(search),
you are missing csKind, maybe change this line to
data: "{searchClause: '" + search + "',csKind: '" + csKind + "'}",
And change your method to :
public static void AutoComplete_Press(string searchClause, string csKind)
The url seems to be wrong if you ask me. Open up your console in the browser and see what it says, it will be throwing cant connect/connection refused error. Also open network in the browser and you can check what http response you are getting. This will help u start up diagnosing the problem.
Related
I download a source code, and I tried it in Visual Studio 2013, and it didn't work, but it works when I use Visual Studio 2010, which I think there is a trick in ASP.Net 4.5 that I don't know about. Here is the code:
function Load(Skip, Take) {
$('#divPostsLoader').html('<img src="../ProgressBar/ajax-loader.gif">');
//send a query to server side to present new content
$.ajax({
type: "POST",
url: "/Grid/LoadImages",
data: "{ Skip:" + Skip + ", Take:" + Take + " }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
if (data != "") {
$('.thumb').append(data.d);
}
$('#divPostsLoader').empty();
}
})
};
And this is the Webmethod that never run:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string LoadImages(int Skip, int Take)
{
System.Threading.Thread.Sleep(2000);
StringBuilder GetImages = new StringBuilder();
string Imagespath = HttpContext.Current.Server.MapPath("~/Images/");
string SitePath = HttpContext.Current.Server.MapPath("~");
var Files = (from file in Directory.GetFiles(Imagespath) select new { image = file.Replace(SitePath, "") }).Skip(Skip).Take(Take);
foreach (var file in Files)
{
var imageSrc = file.image.Replace("\\","/").Substring(1); //Remove First '/' from image path
GetImages.AppendFormat("<a>");
GetImages.AppendFormat("<li>");
GetImages.AppendFormat(string.Format("<img src='{0}'/>", imageSrc));
GetImages.AppendFormat("</li>");
GetImages.AppendFormat("</a>");
}
return GetImages.ToString();
}
Any suggestion?
Thanks.
Have you tried stepping through your javascript? I bet you're getting a 500 error.
UPDATE
OP is getting 401 unauthorized when the AJAX request tries to call the WebMethod.
Once you allow authentication, you have to set AutoRedirectMode = RedirectMode.Off in your AppStart/RouteConfig.cs.
See more here
I am sending a complex string (which is a combination of the style attribute, ID and label text) from the script using $.ajax() . I went through a couple of questions on similar problems. But maybe I am not able to understand where am I getting it wrong.
This is the script I am using :
$(".btnSaveStyle").click(function (e) {
var comp1Style = "";
var comp2Style = "";
$(".box").children(".comp1").each(function () {
var style = $(this).attr('style');
var title = $(this).text();
var componentClass = $(this).attr('class');
comp1Style = comp1Style + style + "#" + componentClass + "#" + title + "$";
});
alert(comp1Style); //I get the style here
$.ajax({
type: "POST",
async: true,
url: 'AjaxRecieveStyle.aspx/GetStyle',
data: comp1Style
});
And in the C# I am accessing it in the following way :
[WebMethod]
protected void GetStyle(string style)
{
var recievedStyle = style;
Customer customer = (Customer)Session["existing_user"];
if (customer != null)
{
EventComponent eventComponent = new EventComponent();
string txtComp1 = recievedStyle;
string[] separateComponents = txtComp1.Split('$');
string[] individualComponent = new string[5];
foreach (string position in separateComponents)
{
individualComponent = position.Split('#');
if (individualComponent[0].Equals(""))
{
//do nothing
}
else
{
eventComponent.EventID = 1;
eventComponent.Image = "";
eventComponent.Style = individualComponent[0].ToString();
eventComponent.ComponentType = individualComponent[1].ToString();
eventComponent.Title = individualComponent[2].ToString();
int id = new EventComponentLogic().Insert(eventComponent);
}
}
}
}
Now :
1) : Should I use a JSON object to pass the data ?
OR
2) : Please show me what am i doing wrong in here ?
1) Yes it's better to send data using JSON - I mean, it'd be much easier to understand what's happening when anyone will look at that code in a year from now. And it's also much easier to extend the protocol based on JSON.
2) I suggest you to add logging at the very beginning of the GetStyle(string style) method. Then please try to get to it by explicitly typing the URL in your browser (or better using PostMan - see below for a link, PostMan will help you with testing POST requests as I see you have a POST request there) and ensure that the web-server code works.
And only if it works then please try your front-end AJAX request.
I suppose that you don't handle POST request correctly in your WebAPI. It will only handle GET requests. Please look at this SO question for details: Simple post to Web Api
3) Link to PostMan: https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en
Did some digging and came up with this link: http://www.aspsnippets.com/Articles/Calling-ASPNet-WebMethod-using-jQuery-AJAX.aspx
The source code from the website shows that you may be missing some key features in your ajax call:
function ShowCurrentTime() {
$.ajax({
type: "POST",
url: "Default.aspx/GetCurrentTime",
data: '{name: "' + $("#<%=txtUserName.ClientID%>")[0].value + '" }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function(response) {
alert(response.d);
}
});
}
While this is (obviously) intended for their example you see that they set the following attributes that you do not
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function(response) {
alert(response.d);
}
While the success and failure attributes are definitely optional I believe that setting your content type and datatype would really help you out here.
I changed my script to the following :
$.ajax({
type: "POST",
async: true,
url: 'AjaxRecieveStyle.aspx',
data: { style: comp1Style } //as I want to pass the parameter 'style' which is internally a JSON array.
});
I fetched the variable style in my C# in the following way (without using [WebServices]) :
I wrote a method GetStyle(string style) to get the data being sent from the ajax call.
Note: I did not call AjaxRecieveStyle/GetStyle from my script as the method is not accessible in my C# method . The data is actually received from the Page_Load method.
I access the variable sent from the script using Request.Params["style"].
My C# method is :
protected void Page_Load(object sender, EventArgs e)
{
GetStyle(Request.Params["style"]);
}
protected void GetStyle(string style)
{
var recievedStyle = style;
//do something on the recieved data!
}
This wil be an alternative to anyone who don't want to send JSON data actually !But sending data using JSON format will increase the readability of the code..
I want to call a web method in asp.net c# application using the following code
Jquery:
jQuery.ajax({
url: 'AddToCart.aspx/AddTo_Cart',
type: "POST",
data: "{'quantity' : " + total_qty + ",'itemId':" + itemId + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function () {
alert("Start!!! ");
},
success: function (data) {
alert("a");
},
failure: function (msg) { alert("Sorry!!! "); }
});
C# Code:
[System.Web.Services.WebMethod]
public static string AddTo_Cart(int quantity, int itemId)
{
SpiritsShared.ShoppingCart.AddItem(itemId, quantity);
return "Add";
}
But it always call page_load. How can i fix it?
There are quite a few elements of the $.Ajax() that can cause issues if they are not defined correctly. I would suggest rewritting your javascript in its most basic form, you will most likely find that it works fine.
Script example:
$.ajax({
type: "POST",
url: '/Default.aspx/TestMethod',
data: '{message: "HAI" }',
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data);
},
failure: function (response) {
alert(response.d);
}
});
WebMethod example:
[WebMethod]
public static string TestMethod(string message)
{
return "The message" + message;
}
This is a bit late, but I just stumbled on this problem, trying to resolve my own problem of this kind. I then realized that I had this line in the ajax post wrong:
data: "{'quantity' : " + total_qty + ",'itemId':" + itemId + "}",
It should be:
data: "{quantity : '" + total_qty + "',itemId: '" + itemId + "'}",
As well as the WebMethod to:
public static string AddTo_Cart(string quantity, string itemId)
And this resolved my problem.
Hope it may be of help to someone else as well.
Necro'ing this Question ;)
You need to change the data being sent as Stringified JSON, that way you can modularize the Ajax call into a single supportable function.
First Step: Extract data construction
/***
* This helper is used to call WebMethods from the page WebMethods.aspx
*
* #method - String value; the name of the Web Method to execute
* #data - JSON Object; the JSON structure data to pass, it will be Stringified
* before sending
* #beforeSend - Function(xhr, sett)
* #success - Function(data, status, xhr)
* #error - Function(xhr, status, err)
*/
function AddToCartAjax(method, data, beforeSend, success, error) {
$.ajax({
url: 'AddToCart.aspx/', + method,
data: JSON.stringify(data),
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
beforeSend: beforeSend,
success: success,
error: error
})
}
Second Step: Generalize WebMethod
[WebMethod]
public static string AddTo_Cart ( object items ) {
var js = new JavaScriptSerializer();
var json = js.ConvertToType<Dictionary<string , int>>( items );
SpiritsShared.ShoppingCart.AddItem(json["itemId"], json["quantity"]);
return "Add";
}
Third Step: Call it where you need it
This can be called just about anywhere, JS-file, HTML-file, or Server-side construction.
var items = { "quantity": total_qty, "itemId": itemId };
AddToCartAjax("AddTo_Cart", items,
function (xhr, sett) { // #beforeSend
alert("Start!!!");
}, function (data, status, xhr) { // #success
alert("a");
}, function(xhr, status, err){ // #error
alert("Sorry!!!");
});
One problem here is that your method expects int values while you are passing string from ajax call. Try to change it to string and parse inside the webmethod if necessary :
[System.Web.Services.WebMethod]
public static string AddTo_Cart(string quantity, string itemId)
{
//parse parameters here
SpiritsShared.ShoppingCart.AddItem(itemId, quantity);
return "Add";
}
Edit : or Pass int parameters from ajax call.
I'm not sure why that isn't working, It works fine on my test. But here is an alternative technique that might help.
Instead of calling the method in the AJAX url, just use the page .aspx url, and add the method as a parameter in the data object. Then when it calls page_load, your data will be in the Request.Form variable.
jQuery
jQuery.ajax({
url: 'AddToCart.aspx',
type: "POST",
data: {
method: 'AddTo_Cart', quantity: total_qty, itemId: itemId
},
dataType: "json",
beforeSend: function () {
alert("Start!!! ");
},
success: function (data) {
alert("a");
},
failure: function (msg) { alert("Sorry!!! "); }
});
C# Page Load:
if (!Page.IsPostBack)
{
if (Request.Form["method"] == "AddTo_Cart")
{
int q, id;
int.TryParse(Request.Form["quantity"], out q);
int.TryParse(Request.Form["itemId"], out id);
AddTo_Cart(q,id);
}
}
The problem is at [System.Web.Services.WebMethod], add [WebMethod(EnableSession = false)] and you could get rid of page life cycle, by default EnableSession is true in Page and making page to come in life though life cycle events..
Please refer below page for more details
http://msdn.microsoft.com/en-us/library/system.web.configuration.pagessection.enablesessionstate.aspx
you need to JSON.stringify the data parameter before sending it.
Here is your answer.
use
jquery.json-2.2.min.js
and
jquery-1.8.3.min.js
Javascript :
function CallAddToCart(eitemId, equantity) {
var itemId = Number(eitemId);
var quantity = equantity;
var dataValue = "{itemId:'" + itemId+ "', quantity :'"+ quantity "'}" ;
$.ajax({
url: "AddToCart.aspx/AddTo_Cart",
type: "POST",
dataType: "json",
data: dataValue,
contentType: "application/json; charset=utf-8",
success: function (msg) {
alert("Success");
},
error: function () { alert(arguments[2]); }
});
}
and your C# web method should be
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string AddTo_Cart(int itemId, string quantity)
{
SpiritsShared.ShoppingCart.AddItem(itemId, quantity);
return "Item Added Successfully";
}
From any of the button click or any other html control event you can call to the javascript method with the parameter which in turn calls to the webmethod to get the value in json format.
I am calling a WebMethod from jQuery doing the following:
function WebMethod(fn, paramArray, successFn, errorFn) {
var paramList = {};
if (paramArray.length > 0) {
for (var i = 0; i < paramArray.length; i += 2) {
paramList[paramArray[i]] = paramArray[i + 1];
}
}
var params = $.toJSON(paramList);
$.ajax({
type: 'POST',
url: '../../PricingEngine/ContractView.aspx' + '/' + fn,
contentType: 'application/json; charset=utf-8',
data: params,
dataType: 'json',
success: successFn,
error: function(xhr, status, error) {
// Display a generic error for now.
alert("AJAX Error!");
}
});
}
// Used returned object to populate every field
function updateTextFields(result) {
//do some processing here
}
function failed(result) {
alert('failed');
}
// EVENTS
// ------------------------------------------------------------
$(".editableField").keydown(function(e) {
WebMethod('PriceContract',
[
'AQ', aq.val(),
'SOQ', soq.val()
], updateTextFields, failed);
});
The JSON string after the .toJSON has been called:
{"AQ":"140000","SOQ":"1169"}
The C# method
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static ContractsListPricing PriceContract(string AQ, string SOQ)
{
ContractsListPricing clp = new ContractsListPricing();
clp.Aq = 1;
clp.Soq = 2;
return clp;
}
This is returning the following error:
Invalid JSON: (Followed by the complete HTML of the current page).
Please take no notice of the logic in the C# as this isn't implemented yet. I am using the jquery-json plugin to parse the JSON.
Thanks
Ive run a demo of your code and got it working fine. Have you checked that you have the ScriptModule Handler set correctly in your web.config?
You're sure the exact url is '../../PricingEngine/ContractView.aspx' + '/' + fn ?
Because ContractView.aspx IS your current webpage
I have simplified my code to just passing the array but still am not having any luck
When I step through the code and get to the point of the ajax request
jsonText contains:
[{"UserId":"8"},{"UserId":"9"},{"UserId":"5"},{"UserId":"13"},{"UserId":"6"},{"UserId":"11"}]
and
jsonTextSerialized contains:
"[{\"UserId\":\"8\"},{\"UserId\":\"9\"},{\"UserId\":\"5\"},{\"UserId\":\"13\"},{\"UserId\":\"6\"},{\"UserId\":\"11\"}]"
function GetUserSchedules() {
var jsonText = $.toJSON(arrParams);
var jsonTextSerialized = Sys.Serialization.JavaScriptSerializer.serialize(jsonText);
$.ajax({
type: "POST",
url: "/myurl/jquery.aspx/GenerateUserSchedules",
data: "{'data':'" + jsonTextSerialized + "'}",
contentType: "application/json",
dataType: "json",
success: function () { alert('Made It!'); },
error: function (result) { alert(Failed: ' + result.responseText);
});
My code behind has
[Serializable]
public class User
{
public int UserId { get; set; }
}
[System.Web.Script.Services.ScriptMethod]
[System.Web.Services.WebMethod]
public static void GenerateUserSchedules(User[] data)
{
//do stuff
}
The responseText is:
"There was an error processing the request.","StackTrace":"","ExceptionType":""}
What am I doing wrong?
MY SOLUTION WITH YOUR HELP:
Thank you all for your efforts. I can't express how grateful for all your input. I am embarassed to admit it, but I had been stuck on this for days.
I see from all your answers that there are various ways to approach this.
I like the JSON.stringify solution best for two reasons:
It removes the danger of inadvertant
typos when I add parameters to the
ajax request.
According to Oleg, it
is a more efficient way to serialize
the data objects
So here is how I decided to resolve the issue.
<script type="text/javascript">
var startDate;
var endDate;
var ddlViewSelectedItem;
var ddlViewSelectedValue;
var ddlOrgSelectedValue;
var arrUsers= [];
$(document).ready(function () {
ddlViewSelectedItem = $('#<%=ddlView.ClientID %> option:selected').text();
ddlViewSelectedValue = $('#<%=ddlView.ClientID %> option:selected').val();
ddlOrgSelectedValue = $('#<%=ddlOrganization.ClientID %> option:selected').val();
$.when(GetStartDate(), GetEndDate()) //these populate strt and end dates
.then(function () {
GetUserIDs(); // populates arrUsers
GetUserSchedules();
})
.fail(function () {
failureAlertMsg();
})
});
// Here I use JSON.stringify because it simplifies adding params. No messy single and/or double quote confusion. I love this. Must include json2.js from https://github.com/douglascrockford/JSON-js/blob/master/json2.js
function GetUserSchedules() {
var jsonTextStringified = JSON.stringify({ data: arrParams, startDate: startDate, endDate: endDate, ddlViewSelectedItem: ddlViewSelectedItem, ddlViewSelectedValue: ddlViewSelectedValue, ddlOrgSelectedValue: ddlOrgSelectedValue });
$.ajax({
type: "POST",
url: "/myurl/jquery.aspx/GenerateUserSchedules", // this is a call to a pagemethod, not a webservice, so .aspx is correct
data: jsonTextStringified,
contentType: "application/json",
dataType: "json",
success: function () { alert('Sweet! Made It!'); }
,
error: function (result) { alert('Failed!: ' + result.responseText); }
});
}
Code behind:
[Serializable]
public class User
{
public string UserId { get; set; }
}
[System.Web.Script.Services.ScriptMethod]
[System.Web.Services.WebMethod]
public static void GenerateUserSchedules(User[] data, string startDate, string endDate, string ddlViewSelectedItem, string ddlViewSelectedValue, string ddlOrgSelectedValue)
{
//do cool stuff and eventually send data back
}
Thank you again for all your help
Look at the close answer here, here or here. Many people made the same errors.
In the initialization of JavaScript objects you can use both quotes and double quotes, but in the JSON data only double quotes are permitted.
You should no time make JSON serialization manual like {"{'startDate':'" + startDate + "', ... and not use old $.toJSON jQuery plugin. The best way is to use JSON.stringify function from the json2.js. The most current version of the web browsers support the function in the native code, so it work very quickly.
One more thing which look strange is the path "/myurl/jquery.aspx/GenerateUserSchedules" instead of "/myurl/jquery.asmx/GenerateUserSchedules" (asmx instead of aspx).
In your case you should use
data: JSON.stringify({
startDate: startDate,
endDate: endDate,
ddlViewSelectedItem: ddlViewSelectedItem,
ddlViewSelectedValue: ddlViewSelectedValue,
ddlOrgSelectedValue: ddlOrgSelectedValue
})
in case of usage of type: "POST" and
data: {
startDate: JSON.stringify(startDate),
endDate: JSON.stringify(endDate),
ddlViewSelectedItem: JSON.stringify(ddlViewSelectedItem),
ddlViewSelectedValue: JSON.stringify(ddlViewSelectedValue),
ddlOrgSelectedValue: JSON.stringify(ddlOrgSelectedValue)
}
if you decide to use type: "GET".
It is important to send data for all input parameters of the web method. At least you should send parameters with the null value as the input (for nullable objects).
UPDATED: At the time you rewrote your question. So now the answer on the new version of your question.
You should use
$.ajax({
type: "POST",
url: "/myurl/jquery.aspx/GenerateUserSchedules",
data: JSON.stringify({data: [
{UserId:8},{UserId:9},{UserId:5},{UserId:13},{UserId:6},{UserId:11}]}),
contentType: "application/json",
dataType: "json",
success: function () { alert('Made It!'); },
error: function (result) { alert(Failed: ' + result.responseText);
});
The reason is easy. Because you have the method GenerateUserSchedules(User[] data) with the data input parameter you should use JSON.stringify({data: yourData}) as the input. The array of User objects should be array with the items {UserId:8} (or {'UserId':8} or {"UserId":8}), but not {UserId:"8"}.
There are a couple of approaches to do this. If your application uses MS Ajax libraries by any chance then all you need to do on client side is
var jsonText = [{"UserId":"8"},{"UserId":"9"},{"UserId":"5"}];
var jsonTextSerialized = Sys.Serialization.JavaScriptSerializer.serialize(jsonText);
You can then use this jsonTextSerialized with other parameters that you have to send it to your server side code. On server side you can have
public class User{
public Int32 UserId{
get;set;
}
}
[System.Web.Script.Services.ScriptMethod]
[System.Web.Services.WebMethod]
public static void GenerateUserSchedules(string startDate, string endDate, string ddlViewSelectedItem, string ddlViewSelectedValue, string ddlOrgSelectedValue, User[] customObejct)
This should automatically do it for you.
If you are not using MS Ajax, then get JSON2.js from here
http://www.json.org/js.html
You can use this library to serialize your object on client side. On server side things should remain the same.
For more detailed guide and information also check this out
http://forums.asp.net/t/1388935.aspx
Hope this helps!
Nikhil
your custom object should now have the object
could it be as simple as:
data: "{'data':'" + jsonTextSerialized + "'}",
change to
data: '{"data":"' + jsonTextSerialized + '"}',
AND/OR change client side "UserId" to "UserID"
Make sure the json property names and types matchup with the web method parameters.
Your jsonText variable is an array and so the Web method needs a property of an array type to accept it (like in the example Nikhil posted).
So if you were using the web method signature in Nikhil's example and the custom user object, you would need to make the data property for the jquery ajax call to be:
"{'startDate':'" + startDate + "', 'endDate':'" + endDate + "', 'ddlViewSelectedItem':'" + ddlViewSelectedItem + "', 'ddlViewSelectedValue':'" + ddlViewSelectedValue + "', 'ddlOrgSelectedValue':'" + ddlOrgSelectedValue + "','customObejct':" + jsonText + "}"