Ajax.NET bugfixes and new features
I fixed several bugs in the last week. Because of internal complete redesign some objects like DataSet returned wrong to the client-side Javascript. Also some NullReferenceExceptions have been fixed. The proxy files are cached, now.
New features are supporting Bitmap as return value, new .getTable("name") on DataSets to get DataTables instead of the index usage, large data as request arguments (i.e. for contact form or forum), context for the client-side Javascript callback, full Unicode support, new IAjaxObjectConverters, arrays of integer and strings are supported as method arguments:
[Ajax.AjaxMethod]
public string Test18(string[] s)
{
string r = "";
foreach(string ss in s)
r += "<p>" + ss + "</p>\r\n";
return r;
}
To download version 5.5.13.1 click here. The online examples are updated and will replace the UsageGuide document later. You can download the online examples with full source code at http://ajax.schwarz-interactive.de
The source code of the IAjaxObjectConverters will be placed on my web site in the next days. Currently in the download of the examples you will find a IAjaxObjectConverter for System.DateTime.
Updated: DataSets throw a StackOverflowException when using GUIDs. A workaround will be available here: http://weblogs.asp.net/mschwarz/archive/2005/06/02/410061.aspx The bug is fixed in version 5.6.2.1.
26 Comments
Comments have been disabled for this content.
Arno said
Hi Michael, do you want to add more array types?
Günther said
Hi Michael, I got the following error when trying to unzip the new version: Warning: skipping "Ajax.dll", The 32-bit CRC stored in the local header for this file is not the same as the 32-bit CRC stored in the central header.
Therefore, I was not able to unzip ajax.dll.
Günther said
Hmm, I was able to unzip with winrar. I got the (5.5.13.1) version, where did the new version end up?
Have a nice weekend!
Günther said
Anders, thanks for the info. I got the new version now. :-)
Michael Schwarz said
I updated the Ajax.zip, it was still the old one, thanks.
@Arno: Yes, I will go on, but you can do it also by building a IAjaxObjectConverter.
@AndersH: Ok, I will make a change that it is easier to read.
walaqi said
hi,your work is great.i think it is a good prototype for the implement of ajax model.
but i am doubt about what will happen when i use it under asynchronous scenario.
walaqi said
btw:I test your sample.
i think it is not safe if you transform the data which user submiting by querystring when you call the method.i can even call the method by combine the whole url in addressbox of ie
Keith said
Will you release this to the open source community?
Michael Schwarz said
@walaqi: What should happen, the calls are asynchronous calls?!? The second question is no real question, or? Every form you can send is always something you can do directly, there is no more or less security than with typical web sites. Or do you mean something different?
@Keith: See my last posts here. I'd like to start it but I've some problems where to do this.
Nick! said
Michael, I'm not sure if my comment got through to you through the other form, but I'm having a problem with Ajax.NET returning objects with enums -- specifically, the whole application pool crashes. If I remove the enums its fine, doesn't matter what enum I use (my own, DayOfWeek, one from Ajax.net). Only thing I wonder is if it's because I'm using this on .NET Framework 2.0 Beta 2. Are there any known issues with enums at this point on 1.1?
Ajax.NET is great otherwise :) If I can get past the enum problems it's ultra handy, cool stuff! And really, it's quite likely that what I would use this for in a live sense wouldn't use enums anyhow.
Alan W. Cruz said
Couldn't SourceForge work for open sourcing the wrapper? Various OSS projects have their source there.
Michael Schwarz said
@Nick: I will have a look at enums.
walaqi said
will you cache your ashx?
Ryan said
I'm having particular problems returning a DataSet when filled with a DataAdapter...
Imports System.Data
Imports System.Data.SqlClient
Namespace StoredProcedures
Class GetMail
Private Shared sqlAdapter As SqlDataAdapter
Private Shared dsReturn As DataSet
Private Shared sqlCommand As sqlCommand
Shared Function Invoke(ByVal sqlConn As SqlConnection, ByVal UserId As Int64, ByVal Start As Int64, ByVal Amount As Int16, ByRef Count As Int32) As DataSet
sqlCommand = New sqlCommand("sm_GetMail", sqlConn)
With sqlCommand
.CommandType = CommandType.StoredProcedure
.Parameters.Add(New SqlParameter("@UserID", UserId))
.Parameters.Add(New SqlParameter("@StartAt", Start))
.Parameters.Add(New SqlParameter("@Amount", Amount))
.Parameters.Add(New SqlParameter("@TotalMail", Count)).Direction = ParameterDirection.Output
End With
Return ExecuteAdapter(sqlCommand, Count)
End Function
Private Shared Function ExecuteAdapter(ByVal sqlCmd As sqlCommand, ByRef Count As Int32) As DataSet
sqlAdapter = New SqlDataAdapter(sqlCmd)
dsReturn = New DataSet
sqlAdapter.Fill(dsReturn)
sqlAdapter = Nothing
If Object.ReferenceEquals(sqlCmd.Parameters("@Count").Value, System.DBNull.Value) = True Then
Count = 0
End If
Return dsReturn
End Function
End Class
End Namespace
-------------
When I execute the GetMail.Invoke everything seems to be fine the dataset gets populated correctly; however, when it returns via the exposed AjaxMethod I ALWAYS get a System.StackOverflowException in MSCORLIB.DLL.
It errors on a call to System.Reflection.RuntimeFieldInfo.GetValue apparently from a call from PropsFieldsToJSON according to the call stack :\
Is there any possible reason for this?
Ryan said
The Ajax method is fairly simple and looks like..
<Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.Read)> _
Public Function GetMail() As DataSet
Dim pCount As Int32
Return StoredProcedures.GetMail.Invoke(New SqlClient.SqlConnection("serverinfohere"), 1, 1, 50, pCount)
End Function
Michael Schwarz said
@walaqi: Yes, the Javascript files will be cached.
Michael Schwarz said
@Ryan: I know this problem and I am working on that. It is a problem with a child-parent relation.
Ryan said
Any temporary workarounds?
KB said
Is there anyway to access the HttpRequest object from an Ajax Method? If I try to access it inside an Ajax method, it is returning null.
Michael Schwarz said
@KB: Yes, you can use System.Web.HttpContext.Current.Request.
AndersH said
When typing in a expression like this 'javascript:alert(DemoMethods.Test18( ["a\",\"b"] ).value);' at the test page, I would think that the correct response would be '<p>a","b</p>' and not '<p>a\</p><p>"b</p>' as is return now. That is the quotes in the string should not break the string sinse they are escaped and the broken string should be unescaped.
I tried to create a little function that would do the right thing, but maybe urlencoding would be simpler.
private string[] FromJSArray(string s) {
ArrayList list = new ArrayList();
int StartPos = -1;
if (s[0] != '[') throw new FormatException("Must start with a left square bracket");
if (s[s.Length - 1] != ']') throw new FormatException("Must end with a right square bracket");
for (int i = 1; i < s.Length-1; i++) {
Char ch = s[i];
if (ch == '"' && StartPos == -1) {
StartPos = i;
} else if (ch == '\\' && StartPos != -1) {
i++;
} else if (ch == '"' && StartPos != -1) {
list.Add(System.Text.RegularExpressions.Regex.Unescape(s.Substring(StartPos+1, i - StartPos - 1)));
StartPos = -1;
i++;
if (s[i] != ',' && i != s.Length-2) new FormatException("Strings must be seperated by comma");
} else if (StartPos == -1) {
throw new FormatException("Invalid character outside string");
}
}
if (StartPos != -1) throw new FormatException("String not ended");
return (string[])list.ToArray(typeof(string));
}
(The forum doesn't seem to have a preview, so the code indentation will problably look broken)
How to access controls on partial Post Back? said
Is it event possible to access a control from a server function when it is called from the client. All of my contorls are undefined when the server function is run. Do I need to call the OnInit() function or something?
scott e said
Hi Michael,
Sorry for no feedback for a bit... been quite busy. I have noticed with this new version, the support for the Decimal type has not been added -- remember you hooked me up with a version that supported it? Anyhow, could you put that back in the next version?
Otherwise, it's looking great.
Thanks,
se
Michael Third said
I must be doing something wrong, but when returning an ArrayList the following is the response stream:
{'Capacity':4,'Count':4,'IsFixedSize':false,'IsReadOnly':false,'IsSynchronized':false,'SyncRoot':{},'Item':null}
Thanks,
Michael
Alan W. Cruz said
Hi Michael,
In my wrapper I'm using the following code to transform dataset, datatable and datarows into JSON objects, I would like to know if it is optimal or if it's better to find a way to transform the dataset.getxml into JSON format:
Private Function ConvertDataSet(ByVal ds As DataSet) As String
Dim sB As New StringBuilder("{")
sB.Append("'Tables':")
For Each dt As DataTable In ds.Tables
sB.Append(ConvertDataTable(dt))
sB.Append(",")
Next
sB.Remove(sB.ToString.Length - 1, 1)
sB.Append("]}")
Return sB.ToString
End Function
Private Function ConvertDataTable(ByVal dt As DataTable) As String
Dim sB As New StringBuilder("{")
sB.Append("'Name':'") : sB.Append(dt.TableName) : sB.Append("',")
sB.Append("'Rows':[")
For Each dr As DataRow In dt.Rows
sB.Append(ConvertDataRow(dr))
sB.Append(",")
Next
sB.Remove(sB.ToString.Length - 1, 1)
sB.Append("]}")
Return sB.ToString
End Function
Private Function ConvertDataRow(ByVal dr As DataRow) As String
Dim sCol As String
Dim sB As New StringBuilder("{")
For Each col As DataColumn In dr.Table.Columns
sCol = col.ColumnName
sB.Append("'") : sB.Append(sCol) : sB.Append("':")
Select Case dr(sCol).GetType.ToString()
Case "System.Int32"
sB.Append(dr(sCol)) : sB.Append(",")
Case Else
sB.Append("'") : sB.Append(dr(sCol)) : sB.Append("',")
End Select
Next
sB.Remove(sB.ToString.Length - 1, 1)
sB.Append("}")
Return sB.ToString
End Function
Michael Schwarz said
@Michael Third: can you send me more detailed information or a code fragment of the server-side method? Please use my contact form...