I am sending some data from jquery.ajax to aspx, parsing there and writing on response, but that data is coming in error part, I think some error is being occured which is not being shown, but the correct data is getting returned in error part. Code is below.
JQUERY
var json = "{'uname':'" + $("#uname").val() + "','pwd':'" + $("#pwd").val() + "'}";
alert(json);
$.ajax({
type: "POST",
url: "DataProcess.aspx?Save=1",
data: json,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function (msg) {
alert(msg);
},
error: function (msg) { alert("failed: " + msg.responseText); }
});
DataProcess.aspx.cs
namespace Test
{
public partial class DataProcess : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
ProcessAjaxRequest();
}
private void ProcessAjaxRequest()
{
if (Request.ContentType.Contains("json") && Request.QueryString["Save"] != null)
SaveMyData();
}
private void SaveMyData()
{
System.IO.StreamReader sr = new System.IO.StreamReader(Request.InputStream);
string line = "";
line = sr.ReadToEnd();
JObject jo = JObject.Parse(line);
Response.Write(line);
Response.Write((string)jo["uname"]);
Response.Write((string)jo["pwd"]);
}
}
}
So i am getting what ever the response is in the error part, what is wrong?
K i got the problem, above code is correct, Now my other doubt is, can i call a particular nonstatic method from this same aspx.cs, I mean when i tried something like this "DataProcess.aspx/Test?Save=1". It gives error saying not a web method, I declared method as
[WebMethod]
public void Test(){
}
K guys, I thought the problem was gone, just now i observed that, if i write a string to response something like this Response.Write("success"), its comming in jquery error block, but when i write something like this "Response.Write(0);", its comming in success block. The first one should also come, someone explain whats the problem
Thanks
not sure the exact problem but your json looks like a string. it should be like this
var json = {'uname':'" + $("#uname").val() + "','pwd':'" + $("#pwd").val() + "'};
I am assuming that you have already figured out about PageMethods (i.e. a static method decorated with WebMethod keyword).
Regarding your later question, its not possible to use non-static (instance) methods as Page Methods. The reason is quite simple - an instance method could access instance variables including control tree. Without view-state, ASP.NET cannot guarantee a correct control tree state in post-back scenarios. For such needs, UpdatePanel is the way to go - as it provides AJAX within the ASP.NET control model. Page Methods are meant for stream-lined communication where request/response data are minimalistic without overheads (i.e. the only meaningful data that you wants to communicate between client/server).
Related
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..
So, I have done this before and made many many ajax calls
For some reason this one doesn't work =(
What do I need to change to get this one to work?
Previously I had an internal server error 500, but after pasting some working code and renaming methods to shorter names finally it changed over to this error of Unknown web method.
Setup
I am using jQuery to make Ajax calls to WebMethods in my Codebehind for my ASP.NET page.
Here is my C# WebMethod
[WebMethod(EnableSession = true)]
[ScriptMethod]
public string viewApps(string foo)
{
string x = "";
//130 lines of useful code.
x = "0";
return x;
}
Here is the Javascript/jQuery doing the ajax call. It is in side a with all my other ajax calls. The other ones work. This one does not. It triggered by an onclick event in the html.
function viewApps() {
var food = "hamburger";
$.ajax(
{
//send selected makes
type: "POST",
url: "MassUpdater.aspx/viewApps",
dataType: "json",
data: "{foo:" + food + "}",
contentType: "application/json; charset=utf-8",
//process the response
//and populate the list
success: function (msg) {
//just for show
},
error: function (e) {
alert(JSON.stringify(e));
$('#result').innerHTML = "unavailable";
}
});
//to be uncommented later when functionality works.
// populateBrakeConfigs();
// populateBedConfigs();
// populateBodyStyleConfigs();
// populateSpringConfigs();
// populateSteeringConfigs();
// populateWheeleBase();
// populateTransmission();
// populateDriveTypes();
function populateBrakeConfigs() { }
function populateBedConfigs() { }
function populateBodyStyleConfigs() { }
function populateSpringConfigs() { }
function populateSteeringConfigs() { }
function populateWheeleBase() { }
function populateTransmission() { }
function populateDriveTypes() { }
}
The ajax error looks like this:
I am also willing to provide any additional code or information about my project upon request.
The answer unfortunately is that somehow the static keyword got left out of the WebMethod, therefore the ajax call cannot find it.
Edit: Ok, so it looks like posting as application/json needs to be handled server side separate than a form. Is there any better way to post a form in C# as a complicated object? String:String just doesn't cut it. For example, I want to be able to use Dictionary to produce:
{
"data_map":{"some_value":1,"somevalue":"2"},
"also_array_stuffs":["oh look","people might", "want to", "use arrays"],
"integers_too":4
}
---OP---
I've looked on SO and other places. I'm just trying to POST a JSON string to a URL, but the server side keeps interpreting the content as a string instead of a query dict. We have other clients that aren't in c# that hit the server side fine (in HTML, JS, Objective-C, Java), but for some reason the POST data comes back wonky from the C# client.
C# source:
private static Dictionary<string,object> PostRequest(string url, Dictionary<string, object> vals)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(BaseURL+url);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = JsonFx.Json.JsonWriter.Serialize(vals);
//json = json.Substring(1,json.Length-1);
streamWriter.Write(json);
streamWriter.Close();
}
try
{
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string response = streamReader.ReadToEnd();
Dictionary<string,object> retval = JsonFx.Json.JsonReader.Deserialize<Dictionary<string,object>>(response);
return retval;
}
}
catch(WebException e)
{
}
return null;
}
This gets called like:
public static void Main (string[] args)
{
Dictionary<string,object> test = new Dictionary<string, object>();
test.Add("testing",3);
test.Add("testing2","4");
Dictionary<string,object> test2 = PostRequest("unitytest/",test);
Console.WriteLine (test2["testing"]);
}
For whatever reason, this is the request object that gets passed though:
<WSGIRequest
GET:<QueryDict: {}>,
POST:<QueryDict: {u'{"testing":3,"testing2":"4"}': [u'']}>,
COOKIES:{},
META:{'CELERY_LOADER': 'djcelery.loaders.DjangoLoader',
'CONTENT_LENGTH': '28',
'CONTENT_TYPE': 'application/json; charset=utf-8',
'DJANGO_SETTINGS_MODULE': 'settings.local',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HISTTIMEFORMAT': '%F %T ',
'HTTP_CONNECTION': 'close',
'LANG': 'en_US.UTF-8',
'QUERY_STRING': '',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_HOST': '',
'REQUEST_METHOD': 'POST',
'RUN_MAIN': 'true',
'SCRIPT_NAME': u'',
'SERVER_PORT': '9090',
'SERVER_PROTOCOL': 'HTTP/1.0',
'SERVER_SOFTWARE': 'WSGIServer/0.1 Python/2.7.2+',
'SHELL': '/bin/sh',
'SHLVL': '1',
'SSH_TTY': '/dev/pts/0',
'TERM': 'xterm',
'TZ': 'UTC',
'wsgi.errors': <open file '<stderr>', mode 'w' at 0x7f3c30158270>,
'wsgi.file_wrapper': <class 'django.core.servers.basehttp.FileWrapper'>,
'wsgi.input': <socket._fileobject object at 0x405b4d0>,
'wsgi.multiprocess': False,
'wsgi.multithread': True,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)}>
[18/Oct/2012 19:30:07] "POST /api/1.0/unitytest/ HTTP/1.0" 200 31
Some of the more sensitive data in the request has been removed, but is irrelevant
Ugh, I hope I don't make a habit of answering my own questions.
So, Posting Json this way is different than a normal form submission. That means if your server side is expecting just a normal form submission it will not work. The C# code does as it's intended to do, but only submits a JSON string as the POST body. While this may be convenient for people who validate, clean, and handle raw input anyway, keep in mind that if you're using a normal web framework, you will have to write an alternate condition to accept the raw string.
If anybody has an idea how to do a form submission in C# containing objects more complex than a hashmap/dictionary of strings, then I will upvote your answer and give you lots of hugs. For now, this hacky nonsense will have to do.
Well, once, a long time ago I implemented a banking app front end, which, made massive use of JSON for communication between client and server.
It was a clean way to find complex object to and from the server, no need to make complex cleanup or raw string processing.
The key was using WebServices designed for ajax on the server side, your web server class should look like this:
[WebService(Namespace = "http://something.cool.com/")]
[ScriptService] // This is part of the magic
public class UserManagerService : WebService
{
[WebMethod]
[ScriptMethod] // This is too a part of the magic
public MyComplexObject MyMethod(MyComplexInput myParameter)
{
// Here you make your process, read, write, update the database, sms your boss, send a nuke, or whatever...
// Return something to your awaiting client
return new MyComplexObject();
}
}
Now, on your client-side, set things up to make ASP.NET talk to you in JSON, I'm using JQuery for making the ajax requests.
$.ajax({
type: 'POST',
url: "UserManagerService.asmx/MyMethod",
data: {
myParameter:{
prop1: 90,
prop2: "Hallo",
prop3: [1,2,3,4,5],
prop4: {
// Use the complexity you need.
}
}
},
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(response) {
alert(response.d);
}
});
Anything that ASP want to return as the result for your ScriptMethod, is going to be contained in the response.d variable. So, let's say you are returning from the server a complex object, "response.d" is the reference to your object, you access all the object members using the dot notation as usual.
I'm developing a web site for mobile devices that makes ajax calls using jQuery (v 1.7.2) to an ASP.NET (v 2.0.50727) Web Service.
The call works correctly about 95% of the time, but it will randomly fail, returning a 500 internal server error. It fails on the server side before the first line of code is ever executed (the first line writes to the event log).
I haven't seen the call fail using a desktop browser that I remember, but I've seen it fail enough using an iPad. I added
<browserCaps userAgentCacheKeyLength="256">
to the Web Service's web.config file, but that hasn't helped.
javascript:
$.ajax({
type: "POST",
url: serverURL + "/getImage",
data: '{"formURL":"' + url + '", "rowNumber":"'+rowNumber+'"}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg,textStatus, jqXHR) {
...
}, error: function(xhr, ajaxOptions, thrownError) {
...
}
}).done(function(){
console.log("getImage call is done");
});
Example data passed to the web service:
'{"formURL":"fileName.xml", "rowNumber":"1"}'
c#
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string getImage(string formURL, string rowNumber) {
log("Retrieving image of form " + formURL);
string image = "";
string username = /*retrieve username*/;
string password = /*retrieve password*/;
if (username != null && username != "") {
image = /*code to retrieve the image*/;
}
return image;
}
private void log(string message) {
EvLog.WriteToEventLog(DateTime.Now.ToString("MM:dd:yyyy H:mm:ss:fff") + Environment.NewLine + message, 10);
}
The only thing I've found that has slightly helped me, is when the call fails because the response headers from the Web Service contain "jsonerror: true" though I haven't been able to pinpoint why it would randomly fail.
Any help is appreciated!
Assuming it truly is a JSON error, my first thought is that the data being passed into the parameters is incorrect.
The following line is quoting the contents of variables, which I assume is being loaded from somewhere else in the code:
data: '{"formURL":"' + url + '", "rowNumber":"'+rowNumber+'"}',
Assuming you are already making sure rowNumber is an integer value and wouldn't break it, the likelihood is that the 'url' variable is breaking your JSON format. The easiest way this could happen is if you had an unescaped quote in the filename, especially if it's closing your parameter values earlier than expected when it gets concatenated.
There's always the possibility of the characters not being valid for the charset. Do you have an example data that triggers the failure? The example provided looks nice and clean, so I'm assuming it wasn't one of the error cases.
Don't build your data in this way
data: '{"formURL":"' + url + '", "rowNumber":"'+rowNumber+'"}',
It can cause malformed JSON string.
Instead of this stringify your JavaScript object using JSON.stringify method:
data: JSON.stringify({formUrl: url, rowNumber: rowNumber}),
JSON.stringify will make all job for you to represent your object as valid JSON string.
Hopefully this is a fairly easy question. Pardon my ignorance, but I am mostly a PHP/Zend developer, so i am struggling a little in C# and Visual Studio with a json/ajax issue. Is there something obvious I am missing? Any help will be appreciated. Should I be looking at List<>?
Here is the error I receive when I fire the javascript ajax function:
"Unknown web method getwidgets."
I have a dataset in C#, that I run through a JSON converter method. This works well and returns my data in a JSON string.
private widgetsBL widgetsBLObject = new widgetsBL();
[WebMethod]
public String getwidgets()
{
DataSet results = new DataSet();
results = widgetsBLObject.selectTheWidgets();
string jsresults = MyClassLibrary.JqueryTools.GetJSONString(results.Tables[0]);
return jsresults;
}
Here is the jsresults:
{"Table" : [ {"widgetid" : "1","widgetname" : "gizmo1000","widgetdescription" : "very cool widget"},
{"widgetid" : "2","widgetname" : "gizmo2000","widgetdescription" : "decent widget"},
{"widgetid" : "3","widgetname" : "gizmo3000","widgetdescription" : "terrible widget"} ]}
My Javascript call:
$.ajax({
type: "POST",
url: "my.aspx/getwidgets",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
// do stuff with returned data
}
});
getwidgets needs to be static
[WebMethod]
public static String getwidgets()
Remember that if you want your method to be exposed to calls from JavaScript, you need to mark your method with ScriptMethodAttribute. Thus making it look like this:
[ScriptMethod]
[WebMethod]
public static String getwidgets()
{
// Your core here
}
I would return in the method, the object itself and not not a serialized version of it because ASP.NET will JSON serialize it for you if you mark it as [ScriptMethod]; so in the client your variable data.d will contain the object itself and not a simple string that later you have to deserialize, as in your current implementation.
You are mixing technologies: my.aspx is for rendering HTML content, but it can be used to implement REST functionality.
In your case, the easiest would be to implement your code as part of the Page_Loaded() method. Make sure you clear the response first (so you don't have any additional markup in the response). Furthermore, you might want to set the content type of your response to JSON (rather than the default html):
protected void Page_Load(object sender, EventArgs e)
{
Response.ClearContent();
Response.ContentType = "application/json";
DataSet results = new DataSet();
results = widgetsBLObject.selectTheWidgets();
string jsresults = MyClassLibrary.JqueryTools.GetJSONString(results.Tables[0]);
return jsresults;
}
Then retrieve you JSON string at my.aspx (no getwidgets).
Also, since you are not posting any data, consider using GET rather than POST in your AJAX call.