jQuery ajax POST call to ASP.NET Web Service randomly fails - c#

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.

Related

jquery AJAX get encountering undefined error for valid json response

Team - I am new to jquery and facing issue with a valid json response giving unknown error.
Web based C# MVC and backend database is SQL Server. I am using EF.
If I use the below code:
IQueryable dbResult = dbContext.ParentRecord.Where(row => row.Id ==id).Include(row => row.ChildRecord);
if (dbResult != null) { return Ok(dbResult) }
I have verified that the HTTP Status code is 200, the child records are populated correctly and tested the structure to be a valid json.
However the above encounters error in get function. If I remove the Include - the ParentRecord.ChildRecord is null and the get works.
There are no details available about the error in the xhr object. It enters the error function and response is undefined. (code below)
Please note: I have tried with fail function, datatype: "json",
content-type: "application/json, charset=UTF-8" combinations as well.
$.ajax({
url: _url,
cache: false,
error: function (xhr, status, error) {
alert("error : " + xhr.responseText);
}
}).done(function (data) {
alert("inside " + data);
})
Can anyone point me to the root cause of the error? Or help me get more details on the actual error?
include success for e.g:
cache: false,
success: function(reponse){
//parse your serverside code from resonse
}
I hope this works for you.
plus in javascript/jquery, execution stops at the line where it finds an error in code.
and in your ajax you have a extra 'comma' at the end. I'll Bold it.
.ajax({
url: _url,
cache: false,
error: function (xhr, status, error) {
alert("error : " + xhr.responseText);
}, // <=== there's extra comma here. When comma is mentioned it expects for another parameter as you're passing an object. Remove it.
}).done(function (data) {
alert("inside " + data);
})
The issue is traced to Fluent API in C#. Apparently what I did not realize is that jquery is not only expecting a valid json structure but also validating the json response with the respective class.
Unfortunately jquery get error did not provide me any details about the error, which made it hard to detect the anomaly (esp. for newbies like me)
The validation to class failed in this case as it was expecting a ChildRecord.ParentRecord = null field in the response structure. This anomaly is due to Fluent API navigation property definition where the ChildRecord class has the following declaration:
[ForeignKey("PID")]
public virtual ParentRecord ParentRecord { get; set; }
The work around would be to either explicitly set ChildRecord.ParentRecord as null and ensure it is passed into the response or change the Fluent API definition.
I went with the second option.

Sending JSON with a POST to server for parsing - why does this ajax call fail?

So, I send a JSON string to my server for parsing via jQuery ajax. I get the JSON from the Glosbe dictionary's API. Most of the time it works as expected, but there are certain JSONs that fail. What is interesting is that in those cases I get an "Internal server error", but when I tried to debug the application, it seemed like the controller wasn't even called. I don't know how that's even possible.
Here's my View:
$.ajax({
url: '#Url.Action("Parse", "GetMeaning")',
dataType: "json",
data: "ValueToParse=" + jsonToSend, //maybe it's better to send a json instead of a string
type: 'POST',
async: false,
contentType: "application/json; charset=utf-8",
success: function (data) {
//pass the data to the server for parsing
//alert("sendJsonToServer successful, sended " + JSON.stringify(json1) + "got back: " + data);
setMeaningofExpression(expression, data);
$('#expressionTranslations').html(expressionsAsString());
},
error: function (xhr, status, error) {
alert('sendJsonToServer error, tried to send ' + JSON.stringify(jsonToSend) + 'problem: ' + status + " " + error);
}
});
Controller:
[HttpPost]
public JsonResult Parse(String ValueToParse)
{
return Json(Parser.Parse(ValueToParse).ToArray());
}
An example Json that fails:
{"result":"ok","authors":{"1":{"U":"//en.wiktionary.org","id":1,"N":"en.wiktionary.org"},"20":{"U":"//www.slowniki.org.pl/","id":20,"N":"Jerzy Kazojc"},"86":{"U":null,"id":86,"N":"wiki"},"25018":{"U":"//glosbe.com","id":25018,"N":"GlosbeResearch"},"2695":{"U":"//dumps.wikimedia.org/enwiktionary/latest/enwiktionary-latest-pages-articles.xml.bz2","id":2695,"N":"Wiktionary"}},"dest":"hun","phrase":"cat","tuc":[{"authors":[86],"meaningId":-4164218657921168000,"meanings":[{"text":"member of Felidae","language":"eng"},{"text":"domestic species","language":"eng"},{"text":"A common four-legged animal (Felis silvestris) that is often kept as a household pet.","language":"eng"},{"text":"ket","language":"eng"}],"phrase":{"text":"macska","language":"hun"}},{"authors":[2695],"meaningId":-9072797188187576000,"meanings":[{"text":"domestic species","language":"eng"}],"phrase":{"text":"kandúr","language":"hun"}},{"authors":[1],"meaningId":4566464096976442400,"meanings":[{"text":"domestic species","language":"eng"}],"phrase":{"text":"cica","language":"hun"}},{"authors":[25018],"meaningId":3489096155947903000,"phrase":{"text":"hány","language":"hun"}},{"authors":[25018],"meaningId":-557814434056432960,"phrase":{"text":"krapek","language":"hun"}},{"authors":[20],"meaningId":-2600640194269463000,"phrase":{"text":"muksó","language":"hun"}},{"authors":[25018],"meaningId":-4572067174236314000,"phrase":{"text":"rókázik","language":"hun"}},{"authors":[1],"meaningId":null,"meanings":[{"text":"An enthusiast or player of jazz.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(computing) A lsquo;catenate; program and command in Unix that reads one or more files and directs their content to an output device.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(slang, vulgar, African American Vernacular) A vagina; female external genitalia","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(slang) To vomit something.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(Irish, informal) terrible, disastrous.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(archaic, uncountable) The game of ;trap and ball; (also called ;cat and dog;).","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(slang) Any of a variety of earth-moving machines. (from their manufacturer Caterpillar Inc.)","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"raise anchor to cathead","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(nautical) To flog with a cat-o-nine-tails.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"vomit","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(archaic) A sturdy merchant sailing vessel (now only in ;catboat;).","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(slang) Prostitute. [from at least early 15th c.]","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"Any similar animal of the family Felidae, which includes lions, tigers, etc.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(nautical) Contraction of cat-o-nine-tails.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"guy, fellow","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(archaic, uncountable) The trap of the game of ;trap and ball;.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(slang) A person (usually male).","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(nautical) To hoist (the anchor) by its ring so that it hangs at the cathead.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(computing slang) To dump large amounts of data on (an unprepared target) usually with no intention of browsing it carefully.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(derogatory) A spiteful or angry woman. [from earlier 13th c.]","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"A catfish.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"A domesticated subspecies (Felis silvestris catus) of feline animal, commonly kept as a house pet. [from 8th c.]","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(nautical) A strong tackle used to hoist an anchor to the cathead of a ship.","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"(computing) To apply the <b>cat</b> command to (a file).","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"strong tackle used to hoist an anchor to the cathead of a ship","language":"eng"}]},{"authors":[1],"meaningId":null,"meanings":[{"text":"A catamaran.","language":"eng"}]}],"from":"eng"}
I've struggled with something like this too. Try this:
var ValueToSend = {'': jsonToSend };
$.ajax({
url: '#Url.Action("Parse", "GetMeaning")',
data: ValueToSend
type: 'POST',
success:....
Notice that I removed contentType and dataType and that the json string is enclosed in an object with an empty property name. This article helped: http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/ Also make sure you have the routing correctly working on the server; I'd recommend leaving the URL hard-coded until you're sure you've got everyting working so I'd replace url: '#Url.Action("Parse", "GetMeaning")' with the actual route.
The problem was that ASP.NET blocked the Json because it considered it a security risk because of the <b></b> tags.

Cannot pass large json string to another Page with asp.net c# and knockoutjs

I got a problem while working with knockoutJs and asp.net c#.
When I passed a json string from page to another popup page using jquery ajax and knockoutJs for printing.
The problem occur:
When the Json string is small. It works fine, the popup page shows string data in table.
However, when the json string is large. It doesn't work anymore. The error occurs with message:
"Uncaught Sys.ArgumentException: Sys.ArgumentException: Cannot deserialize. The data does not correspond to valid JSON.
Parameter name: data"
Here is my code:
$.ajax({
type: "POST",
url: 'InProgressBrief.aspx/PrintReport',
data: ko.toJSON({ reportData: ko.toJSON(InProgressBriefs.Briefs) }),
async: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
window.open("PrintInProgressBrief.aspx?month=" + InProgressBriefs.Month() + "&year=" + InProgressBriefs.Year(), "", "status=0,toolbar=0,width=1000,height=900");
}
})
Here is my webMethod
[WebMethod]
public static void PrintReport(string reportData)
{
PSCDialog.DataShare = reportData;
}
The popup page recieves the Json tring:
if (PSCDialog.DataShare != null)
return PSCDialog.DataShare as string;
In the popup page UI, I set the knockoutjs variable, my UI javascript code is something like follow:
var InProgressBriefs = {
Briefs: ""
;
$(function(){
InProgressBriefs.Briefs = Sys.Serialization.JavaScriptSerializer.deserialize('<%=ReportJSONData%>');
ko.applyBindings(InProgressBriefs, $('#mainDivPrint')[0]);
})
Would anyone please tell me what is the problem here? I will appreciate your help alot.
Thank you in advance.
One thing that's a little suspicious is the line
data: ko.toJSON({ reportData: ko.toJSON(InProgressBriefs.Briefs) }),
When that's deserialized, you wind up with reportData being a JSON-encoded string rather than a native object. I doubt that's what you want. More likely what you need is
data: ko.toJSON({ reportData: ko.toJS(InProgressBriefs.Briefs) }),
which serializes only once.

How to make a proper authentication with an ASHX Handler

I am using ASP.NET's generic handler (ASHX files) to make server-side pages that can return data to mobile apps and so on. Some of this data is ment to be private. I am using JSON & the POST method as of now.
However, anyone with access to a client-side code (for example the code of the Mobile App), would be able to see what keywords he has to send to the "unpredictable" URL in order to make changes or get data.
I've been doing research for hours and couldn't find a proper way to authenticate that the one sending the JSON request is indeed an approved mobile app.
Example of sending a request to the server with AJAX:
function login()
{
var jsonParam = { name: "test", aname: "secret", pass: "1234", type: "login" }
$.ajax({
url: "AppDatabase.ashx",
type: "post",
data: JSON.stringify(jsonParam),
dataType: "json",
contentType: 'application/json; charset=utf-8',
async:false,
success: function (response) {
alert(response.userEmail);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus + "\r\n" + "Error: " + errorThrown);
}
});
}
Example of receiving the request on the server side:
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "application/json";
JavaScriptSerializer jss = new JavaScriptSerializer();
context.Request.InputStream.Position = 0;
string json;
using (var reader = new StreamReader(context.Request.InputStream))
{
json = reader.ReadToEnd();
}
Dictionary<string, object> dict = jss.Deserialize<Dictionary<string, object>>(json);
if(dict["aname"].ToString() == "secret")
{
// The best security I have right now is a "secret keyword" within the request
}
}
Your current way is very dangerous.
You can use another page that needs username & password to authenticate (for ex. using Session) and then let client to request your ashx file and your ashx should check Session for authentication.
Just a thought:
Are clients (e.g. mobile app) "yours" or is this meant to be some sort of API (for x clients)?
Either way, maybe worth looking into JWT? The idea is that the "payload" (data) is signed (e.g. HMAC SHA-256) and has protections against "replays".
This way, you're not just looking to the auth part - re: both ends need to verify the data so both can ensure such data came from the "right origin" and is (still) valid.
Hth...

response data showing in error part of jquery

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).

Categories

Resources