I use the Microsoft ASP.Net AJAX framework for an autocompletion thingy on a text field (AutoCompleteExtender).
I'm getting an error :
Error during serialization or deserialization using the JSON
JavaScriptSerializer. The length of the string exceeds the value set
on the maxJsonLength property.
Several weird things about this error :
the error is thrown even when every single webservice in my solution return nothing (I altered them to return empty arrays) ;
in the web.config, jsonSerialization maxJsonLength is set to the maximum value of 2147483644, and the webservices in this page are supposed to return a few results ;
it says the source of the error is in a javascript function, but the function is never run, so the webservice is never actually called :
when I delete every AutoCompleteExtender and every call to any webservice from the page, it starts to throw me errors on "end if" inside the aspx. When I remove every "If" in the aspx, it crashes without telling me why. Fun !
<script type="text/javascript">
var tbEntrIdFonctionItemSelected = function(sender, e) {
$get('<%=Me.FormViewContact.FindControl("hdn_AgenceIdFonctionSearch").ClientID%>').value = e.get_value(); // source of the error
}
</script>
What do you think could be the cause of the problem ?
Thanks
OK, so after a bit of tracking, I noticed that a Telerik Combobox was the source of the error. And apparently, it was retreiving (using JSON, hence the error) the very small amount of 140.000 items. No big deal, right ? Hum.
Related
I am working on an asp.net mvc-5 web application and i am using ap.net version 4.5.
Inside my web application I am executing some power-shell scripts to get some hardware info about some servers and VMs, and get back the results inside my code, as follows:
var shell = PowerShell.Create();
string PsCmd =
"add-pssnapin VMware.VimAutomation.Core; $vCenterServer = '"
+ vCenterName.Trim() + "';$vCenterAdmin = '" + vCenterUsername.Trim()
+ "' ;$vCenterPassword = '" + vCenterPassword + "';"
+ System.Environment.NewLine;
PsCmd += "$VIServer = Connect-VIServer -Server $vCenterServer -User $vCenterAdmin -Password $vCenterPassword;" + System.Environment.NewLine;
PsCmd += "Get-VMHost " + System.Environment.NewLine;
shell.Commands.AddScript(PsCmd);
dynamic results = shell.Invoke();
var temp_result = results[0].BaseObject == null ? results[0] : results[0].BaseObject;
var otherIdentityInfo = temp_result.ExtensionData.Hardware.SystemInfo.OtherIdentifyingInfo;
now currently when i run this inside my Visual Studio 2012 professional , i will get the following exception :-
System.StackOverflowException was unhandled
An unhandled exception of type 'System.StackOverflowException' occurred in VimService55.XmlSerializers.dll
on
var otherIdentityInfo = temp_result.ExtensionData.Hardware.SystemInfo.OtherIdentifyingInfo;
So can anyone adivce on this? I know that in general a "StackOverflowException" exception is related to the fact that too many data exists inside the stack, but in my case I do not have control over this data as I am scanning VM server information. So can anyone advice on this please?
EDIT
I am not sure what is really raising the error (the debugger OR the code)? because when i try calling this code on the hosted application inside IIS (not inside Visual Studio) I will get null value for the otherIdentityInfo variable, rather than getting an exception. However, when i debug the code inside Visual Studio using Autos i will get the exception, so as #JmaesP mentioned the exception is being raised by the debugger, but not sure how i can debug this value to see why i am getting null??
A stack overflow exception from an XML serializer might indicate an issue with one of you serializable types. If the type declaration by itself is somewhat recursice, the default XML serializer will end up in inifite recursion. Consider this example:
[Serializable()]
public class Foo : IEnumerable<Foo>
{
public Foo()
{
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
public IEnumerator<Foo> GetEnumerator()
{
throw new NotImplementedException();
}
public void Add(Foo item)
{
throw new NotImplementedException();
}
}
The default XML serializer first tries to figure out how to (de-)serialize an instance of Foo, then it tries to figure out how to (de-)serialize an IEnumerable<Foo>, and to do that it tries to figure out how to (de-)serialize a Foo — resulting in infinite recursion. Typically, a solution to this would to use a custom serializer as described here.
However, in your case the serializer is provided by the third-party component. The exception likely occurs during the serialization/deserialization that is happening when objects are passed from the PowerShell session to your process. So what you could to is to change the object that is returned from the PowerShell script. Instead of returning a VMHost object (requiring to serialize the entire object tree of the VMHost object), you could just return the SystemInfo or OtherIdentifyingInfo.
Large recursions can cause out-of-stack errors.
Your problem is likely that your program is attempting to consume an infinite amount /very large amount of stack.
Without seeing your stack trace, it's a bit difficult to provide a definitive answer, but I think sticking to the basics leads me to believe the source of your StackOverflow is the PsCmd += which continuously adding the data into the stack and results in StackOverflowException.
You can increase the stack size by using the below code:
Editbin.exe /Stack:14000000 "$(TargetDir)MyProject.exe"
Have you analyzed your code to find out that how deep your recursion goes on average? Does it always hit a StackOverflow? Try hardcoding a single entity and see the result.
Since 64 bit code can up more stack space than equivalent 32 bit code, large recursions can cause out-of-stack errors to occur earlier.
In that case, making the stack larger is not a good idea either. Instead we should find the deeply recursive algorithm and make it into an iterative one.
For Stack-Trace;
You can read up this property: Environment.StackTrace.
If the stacktrace exceded a specific threshold that you preset, you can return the function.
Note: From .Net 2.0 and above, you cannot get a StackOverflowException object using a try-catch block.
Let me know if at all it helps you.
I have run into a strange issue dealing with the SelectedValue property of a dropdown list. We were incorrectly setting the SelectedValue property to an invalid selection (zero), but we were not aware of this issue because the exception is not being thrown in development. In development, the code below executes with no problem, but in production it throws an error.
int val = GetValue(); // Note: The GetValue() method is incorrectly returning a 0
ddlDropdown.SelectedValue = val.ToString(); // This line should throw an error
There is no item with a value of 0 in the dropdown, in either the production or dev environments. However, in dev, when this code executes, it simply does nothing. The ddlDropdown.SelectedValue property is a "1" before the line executes and it remains a "1" after the line executes (even though the code is trying to set it to 0). But in production, an error is being logged every time ("ddlDropdown has a SelectedValue which is invalid..."). I've even tried setting the value of the dropdown in the immediate window - setting it to a valid value (a "3", for example) works, but setting it to "0" has the same result - it simply does nothing.
I've researched the error being thrown and I've found references to the error being thrown only during a postback, and not on initial page load. But this code is only called in places that are wrapped in a if (!IsPostBack) so it should only be called on initial page load.
I've fixed the code to no longer incorrectly set the value to 0, but I cannot verify that the fix will work in production since I can't replicate the error in my dev environment.
Can anyone figure out why this code would be throwing an error in production and not in development?
I am using same asp.net page to edit and add data, only with some fields disabled and enabled accordingly. Now when I call webmethod from the add page, it's working fine, but when I call it from edit page, it is not. Though I am using the same javascript function to call the server side method. Please see the code:
.aspx:
function KeyCheck()
{
var KeyID = event.keyCode;
if(KeyID==46)
{
PageMethods.Delete_files(CurrentObj.id);
}
Now when I try to call this same method through edit, its generating following error :
Microsoft JScript runtime error:
Sys.Net.WebServiceFailedException: The
server method 'Delete_files' failed
with the following error:
If you look here they discuss a similar problem. Although the last answer wasn't selected I would still recommend doing what he says. After your first parameter you can pass two function callbacks; one for a successful Ajax call and one for a failure.
Your function should look more like this:
var onDeleteSuccess = function(result) {
//Successfully deleted files, maybe display confirmation to user.
};
var OnDeleteError = function(result) {
//Deleting files unsuccessful, display error to user.
};
PageMethods.Delete_files(CurrentObj.id, onDeleteSuccess, OnDeleteError);
Try adding the "missing" (although they should be optional) parameters to your PageMethod call and see if that solves it.
Edit:
I found a closed bug at connect.microsoft.com about this problem. Have you tried using the page only in IE7? If so, test it in other browsers and see if it works. If it does your only option may be to upgrade IE7 to a newer version or re-open the issue.
Edit after comments:
Try placing this code before your PageMethods.Delete_files function call:
PageMethods.set_path("PageYouAreTransferringto.aspx");
I think the handler you're calling is confused about which server-side page method to call since it appears (to the browser and JavaScript) that you're on a different page.
I'm trying to override the onError event handler of a web form to allow "A potentially dangerous Request.Form value was detected from the client" type errors to be handled within the form rather than ending up at the application level error handler.
I found some sample code like this :
protected override void OnError(EventArgs e)
{
// At this point we have information about the error
HttpContext ctx = HttpContext.Current;
Exception exception = ctx.Server.GetLastError();
string errorInfo =
"<br>Offending URL: " + ctx.Request.Url.ToString() +
"<br>Source: " + exception.Source +
"<br>Message: " + exception.Message +
"<br>Stack trace: " + exception.StackTrace;
ctx.Response.Write(errorInfo);
// --------------------------------------------------
// To let the page finish running we clear the error
// --------------------------------------------------
ctx.Server.ClearError();
base.OnError(e);
}
Which satisfactorily catches the error and writes an error message out to the screen but what I really want to do is to be aware of the error when Page_Load fires and so be able to display a 'normal' error message on the webform.
I'm sure there's a good way to do this but I don't know it ! Suggestions ?
(BTW for various reason I don't want to turn off the checking at either form or app level and neither do I wish to rely on Javascript - thanks)
You actually can catch the error at the page level, but it will kill the page lifecycle. So you have to use a trick to get around it. Example:
public override void ProcessRequest(HttpContext context)
{
try
{
base.ProcessRequest(context);
}
catch(HttpRequestValidationException ex)
{
context.Response.Redirect("HandleValidationError.aspx");
}
}
HandleValidationError.aspx can be anything, including a redirection back to the same page (perhaps with a querystring with information regarding the error, e.g. "ContactForm.aspx?error=Invalid+Request")
I think I understand what you want to do, but I'm afraid it might be impossible. When your ASP.NET page performs a postback, a new thread is created on the server to handle the request. Before your page lifecycle even has a chance to begin, the offending XSS is found and an exception is thrown. Once this exception is thrown, you are "evicted" from the ASP.NET page lifecycle and there is no way to re-enter it. At this point, the only thing you can do on the client side is output the error, or redirect to an error page.
What you seem to want to do is catch the exception, write it out somewhere on the page, and continue with the ASP.NET page lifecycle (i.e. restoring the control tree, restoring viewstate, invoking event handlers, etc). The problem is once an unhandled exception is thrown you no longer have access to the ASP.NET page lifecycle. In this particular case, there is nowhere to put a try/catch block because the exception is thrown internally from the ASP.NET lifecycle before your own code is called.
I know you said you don't want to rely on Javascript, but in this case I think using Javascript is the only way to get the behavior you want. You can still keep server-side validation, just in case your users disable Javascript or type some input that your Javascript doesn't handle.
I don't think you'll be able to handle the error in the Page_load event. In the ASP.NET Page Life cycle validation events occur after the page loads.
Maybe you can add a hidden div (<asp:Panel Visible=false ...) that contains your "normal error message". if the OnError event fires display the error message div.
jason
Ran into an “Out of Stack Space” error trying to serialize an ASP.Net AJAX Array object.
Here is the scenario with simplified code:
Default.aspx
MainScript.js
function getObject(){
return new Array();
}
function function1(obj){
var s=Sys.Serialization.JavaScriptSerializer.serialize(obj);
alert(s);
}
function function2(){
var obj=getObject();
var s=Sys.Serialization.JavaScriptSerializer.serialize(obj);
alert(s);
}
Content.aspx
ContentScript.js
function serializeObject(){
var obj=window.top.getObject();
window.top.function1(obj); // <– This works fine
obj=new Array();
window.top.function1(obj); // <– this causes an Out of Stack Space error
}
The code for the sample pages and JavaScript is here.
Posting the code for the aspx pages here posed a problem. So please check the above link to see the code for the aspx pages.
A web page (default.aspx) with an IFrame on that hosts a content page (content.aspx).
Clicking the “Serialize Object” button calls the JavaScript function serializeObject(). The serialization works fine for Array objects created in the top window (outside the frame). However if the array object is created in the IFrame, serialization bombs with an out of stack space error. I stepped through ASP.Net AJAX JS files and what I discovered is, the process goes into an endless loop trying to figure out the type of the array object. Endless call to Number.IsInstanceOf and pretty soon you get an out of stack error.
Any ideas?
This problem happens because Sys.Serialization.JavaScriptSerializer can't serialize objects from others frames, but only those objects which where instantiated in the current window (which calls serialize() method). The only workaround which is known for me it's making clone of the object from other frame before calling serialize() method.
Example of the clone() methode you can find here (comments in Russian):
link text
I converted your example to a set of static html files, and dowloaded the standalone Microsoft Ajax Library 3.5 to test with. It didn't have issue on either Firefox 3 or IE 7, but I did notice the first alert box displayed [] (an array) and the second {} (an object).
Then, I converted your new Array() code to:
var obj = [];
obj.push(1);
and after that, I got [1] and {"0", 1} is the alert boxes. I don't think the bug is with JavaScriptSerializer, but something to do with passing objects across frames.
I have no way of testing your code right now, but it looks like a bug in JavaScriptSerializer.serialize to me. My guess is that it tries to do some kind of type checking on the array via the CLR and that it doesn't handle an empty array properly.
Have you tried to add an item of a serializable type to the array in your code? If so, what happens?