Monday, March 26, 2012

PageMethods quirk

So here's what I found while using PageMethods in Beta 2

    A server side method needs the attribute [System.Web.Services.WebMethod]A server side method should be static or else you'll get a PageMethods is undefined errorA server side method should NOT be defined in code behind but should be in the ASPX page in <script runat="server"> tag.Here's the quirk. A server side method CANNOT have two parameters with names that differ only in the case of their letters. eg. someParam and SomeParam, even if they are of different types, e.g. string and int This will result in a Sys.ArgumentTypeException with the message Object of type Number cannot be converted to type Function. Parameter name OnSuccess.
    <script runat="server"> [System.Web.Services.WebMethod] public static string SomeMethod(string someParam, int SomeParam) { return "Hello " + someParam + " you are " + SomeParam.ToString() + " years old"; } </script>
    <script type="text/javascript" language="javascript"> function CallMethod() { var age = 28; PageMethods.SomeMethod('MyName',age, OnCallResponse); } function OnCallResponse(arg) { alert(arg); } </script>
    Change the SomeParam to age and it will work.

So my question is : Is this a bug, quirk or by design? If a bug or quirk will it be fixed? Sure one NEVER names two parameters the same with just a change in the case but then again, NEVER say NEVER.

Thanks

I SO MUCH SUPPORT your finding #3. It's so stupid that the server side code won't work in code-behind but inline code would work. What the heck?

To any MSFT moderator:

Is there any workaround for #3? This is driving me crazy.


Weird, but I just tried to create a page just like yours and it works even if the static method is in the code behind...

This is the class:

public partialclass _Default : System.Web.UI.Page { [WebMethod]public static string GetServerDate() {return DateTime.Now.ToString(); }}


And this is the ASPX:

<%@. Page Language="C#" AutoEventWireup="true" CodeFile="~/Default.aspx.cs" Inherits="_Default" %><%@. Importnamespace="System.Web.Services"%>"-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml">Untitled Page"server"> "form1" runat="server" method="post"> "ScriptManager1" runat="server" />

"button"value="get date" onclick="GetDate();" id="Button1" />

"date" />

"text/javascript">function GetDate(){ var div = document.getElementById("date"); PageMethods.GetServerDate(function (result) { div.innerText = result; });}

Sorry about my last post which is unreadable...Angel

Reposted:

Weird, but I just tried to create a page just like yours and it works even if the static method is in the code behind...

This is the class:

public partialclass _Default : System.Web.UI.Page
{
[WebMethod]
public static string GetServerDate()
{
return DateTime.Now.ToString();
}
}


And this is the ASPX:

<%@. Page Language="C#" AutoEventWireup="true" CodeFile="~/Default.aspx.cs" Inherits="_Default" %><%@. Import namespace="System.Web.Services"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server" method="post"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> <input type="button" value="get date" onclick="GetDate();" id="Button1" /> <div id="date" /> </div> </form> </body></html><script type="text/javascript">function GetDate(){ var div = document.getElementById("date"); PageMethods.GetServerDate(function (result) { div.innerText = result; });}</script>

This looks a bug, thanks for reporting this issue, and it will be fixed in a future build.
-Hao


Hi,

that is not a bug. Remember that vbscript is case unsensitive.


Hi,

I tried the approach of using static methods for PageMethods in AJAX v1.0 Beta 2, but it is not working. The only change that happened is that the error message has changed from "PageMethods is undefined" to "PageMethods is null or not a object.

PLEASE HELP !!!!


Advance,

Where the heck is "vbscript" in whole picture? We are trying to access a WebMethod from Javascript using MS Ajax Beta 2 in the code-behind file.


I was hoping this would have been corrected in Beta 2. I guess I'll keep using the ATLAS CTP until this is resolved. Oh well, maybe in build 3??


hello.,

this is correct. the problem is related with the EnsureParameters of the WebServiceMethodData class. I don't know why, but it's "eating parameters" when they have the same name and differ only in case. here's the "bad" code:

privatevoidEnsureParameters()
{
if (this._parameterData ==null)
{
lock (this)
{
Dictionary<string,WebServiceParameterData>dictionary1 =newDictionary<string,WebServiceParameterData>(StringComparer.OrdinalIgnoreCase);
intnum1 =0;
foreach (ParameterInfoinfo1inthis._methodInfo.GetParameters())
{
dictionary1[info1.Name] =newWebServiceParameterData(info1,num1);
num1++;
}
this._parameterData =dictionary1;
}
}
}
 
I've tried reproducing this with a simple method and i get the 2 parameters and if i add them to a dictionary, i get 2 entries. this is not happening here (yes, i've used reeflection to reproduce what's going on and i can say that the dic only has one parameter.
if anyone have an idea on why is that, please,share with us!
thanks. 


hi.

dom't you hate it when you spend 1 hour looking at code and writing reflection just to see that the damn thing is right in front of you?:

newDictionary<string,WebServiceParameterData>(StringComparer.OrdinalIgnoreCase);
thanks Garbin!
 
 

Yeah, there are two places in the code that are using OrdinalIgnoreCase comparers which is what's causing the problem, removing the IgnoreCase for both dictionaries fixes the problem.

Hope that helps,
-Hao


hello.

does that mena that it'll be removed in the next release?


Yes I've already fixed it in the codebase.

Hope that helps,
-Hao

No comments:

Post a Comment