Wednesday, March 21, 2012

web service "is not defined"

I recently upgraded to Ajax 1.0 from ATLAS and now my web services are not working. My service references are not working, I get the "[namespace] is not defined" JS error. However, i can see that the [webservice].asmx/JSDEBUG scripts are being referenced fine. I assume the problem is with my configuration; here is the (important) contents of my Web.Config:

12<configuration>3<configSections>4<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">5<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">6<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>7<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">8<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" />9<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />10<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />11</sectionGroup>12</sectionGroup>13</sectionGroup>14</configSections>1516<system.web>17<pages enableEventValidation="false" viewStateEncryptionMode="Never">18<controls>19<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>20</controls>21</pages>2223<httpHandlers>24<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>25<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>26<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>27<add verb="*" path="CaptchaImage.aspx" type="JSM.OpenFrame.HttpHandlers.CaptchaImageHandler"/>28<remove verb="*" path="*.asmx"/>29</httpHandlers>3031<httpModules>32<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>33</httpModules>3435<compilation debug="true">36<assemblies>37<add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>38<add assembly="Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>39<add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>40<add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>41</assemblies>42</compilation>4344<authentication mode="Windows"/>4546<customErrors mode="Off" defaultRedirect="GenericErrorPage.htm">47<error statusCode="403" redirect="NoAccess.htm"/>48<error statusCode="404" redirect="FileNotFound.htm"/>49</customErrors>50</system.web>5152<system.web.extensions>53<scripting>54<scriptResourceHandler enableCompression="true" enableCaching="true" />55</scripting>56</system.web.extensions>5758<system.webServer>59<validation validateIntegratedModeConfiguration="false"/>6061<modules>62<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>63</modules>6465<handlers>66<remove name="WebServiceHandlerFactory-Integrated" />67<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>68<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>69<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />70</handlers>71</system.webServer>72</configuration>

Is your webservice flagged with the [ScriptService] attribute? If not, there's your problem. the new version uses that attribute to decide which services need to be serialized as JS objects.


Thanks, I didn't know that. I marked my service with [ScriptService] and also marked a method with [ScriptMethod] and I still get the "is not defined" error. Anything else I'm missing?
Might be the fact that you're removing your asmx handler after you add it.. . Put the <remove> as the first entry of the HttpHandlers section and see if that helps.
Moved that but am still getting the JS error. Thanks.

HI joshmccullough,

I think you have to provide us with more information:

What assembly is referenced in you project: System.web.extensions?

Paste your code of you webservice and also the webpage that's calling it. Thanks in advance!

Regards,


I am using a master page. I have a validation control which uses a webservice (see code below); this is where the service reference is added to the page. Note that the RenderJavaScript method is called during PreRender. There is more code involved but short of posting my whole project, here is the important stuff...

Web Service:

1"C#" Class="JSM.OpenFrame.WebServices.GenericLiveValidation" %>2using System;3using System.Web;4using System.Collections;5using System.Web.Services;6using System.Web.Services.Protocols;7using System.Web.Script.Services;8using JSM.OpenFrame.Common;9using JSM.OpenFrame.DataObjects;10using JSM.OpenFrame.Util;1112namespace JSM.OpenFrame.WebServices13{14 [WebService(Namespace ="JSM.OpenFrame.WebServices")]15 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]16 [ScriptService]17public class GenericLiveValidation : System.Web.Services.WebService18 {19 [WebMethod]20public LiveValidationResponse ValidateEmailAddress(string emailAddress)21 {22if (!RegExUtil.ValidateEmailAddress(emailAddress))23return new LiveValidationResponse(false,"The email address field is invalid. Email addresses must be in the form \"user@.host.com\".");24else if (ContactUtil.DoesEmailAddressExist(emailAddress))25return new LiveValidationResponse(false,"This email address is already in use. Please try another.");26else27 return new LiveValidationResponse(true);28 }2930 [WebMethod]31 [ScriptMethod]32public LiveValidationResponse ValidatePassword(string username,string password)33 {34 JSM.OpenFrame.Util.LoginUtil.LoginResult result = LoginUtil.ProcessLogin(username, password);3536if (result == LoginUtil.LoginResult.BadPassword)37return new LiveValidationResponse(false,"The password you entered is not correct.");3839return new LiveValidationResponse(true);40 }41 }42}

Page:

1<%@. Page Language="C#" MasterPageFile="~/Main.master" AutoEventWireup="True" Inherits="MyAccount.AccountInfo" Title="Change Password" Codebehind="AccountInfo.aspx.cs" %>2<%@. MasterType VirtualPath="~/Main.master" %>3<%@. Register TagPrefix="WebControls" Assembly="JSM.OpenFrame" Namespace="JSM.OpenFrame.WebControls" %>4<%@. Register TagPrefix="Validation" Assembly="JSM.OpenFrame" Namespace="JSM.OpenFrame.WebControls.Validation" %>56<asp:Content ID="Content" ContentPlaceHolderID="_contentPlaceHolder" Runat="Server">7 <table cellspacing="1" cellpadding="2" class="Form_Table">8 <tbody>9 <tr>10 <td class="Form_Table_Label">Current Password:</td>11 <td class="Form_Table_Input" style="width: 250px;">12 <asp:TextBox ID="currentPassword" runat="server" CssClass="Form_Textbox_Wide" TextMode="Password" />13 </td>14 </tr>15 <tr>16 <td colspan="2" class="Form_Table_Seperator"></td>17 </tr>18 <tr>19 <td class="Form_Table_Label">New Password:</td>20 <td class="Form_Table_Input">21 <asp:TextBox ID="newPassword1" runat="server" CssClass="Form_Textbox_Wide" TextMode="Password" />22 </td>23 </tr>24 <tr>25 <td class="Form_Table_Label">New Password (again):</td>26 <td class="Form_Table_Input">27 <asp:TextBox ID="newPassword2" runat="server" CssClass="Form_Textbox_Wide" TextMode="Password" />28 </td>29 </tr>30 <tr>31 <td colspan="2" class="Form_Table_ButtonRow">32 <asp:Button ID="saveButton" runat="server" Text="Save" CssClass="Form_Button_Footer" />33 </td>34 </tr>35 </tbody>36 </table>37 <Validation:FormValidator runat="server">38 <Validation:LiveValidator runat="server" Required="true" TargetControlID="currentPassword" ServicePath="~/Services/GenericLiveValidation.asmx" ServiceMethod="JSM.OpenFrame.WebServices.GenericLiveValidation.ValidatePassword" />39 </Validation:FormValidator>40</asp:Content>

LiveValidator control:

1using System;2using System.Collections.Generic;3using System.Text;4using System.Web.UI.WebControls;5using System.Collections.Specialized;6using System.Web.UI;7using JSM.OpenFrame.Util;89namespace JSM.OpenFrame.WebControls.Validation10{11public class LiveValidator : ValidatorBase12 {13private string _servicePath;14private string _serviceMethod;1516public string ServicePath17 {18get {return _servicePath; }19set { _servicePath =value; }20 }2122public string ServiceMethod23 {24get {return _serviceMethod; }25set { _serviceMethod =value; }26 }2728protected override void RenderJavaScript()29 {30 ServiceReference service =new ServiceReference();31 WebControl control = (WebControl)CommonUtil.FindControlRecursive(_targetControlID,this.Page.Controls);32 StringBuilder script =new StringBuilder();3334 service.Path = _servicePath;35 ((BasePage)this.Page).AppendServiceReference(service);3637this.Page.ClientScript.RegisterClientScriptResource(this.GetType(),"JSM.OpenFrame.Resources.LiveValidator.js");38 control.Attributes.Add("onblur",this.ClientID +".Validate();");3940 script.Append("<script language=\"JavaScript\">\n");41 script.Append("\tvar " +this.ClientID +" = new LV_Object(\"" + this.ClientID + "\", document.getElementById(\"" + control.ClientID + "\"), \"" + _serviceMethod + "\", " + _required.ToString().ToLower() +");\n\n");42 script.Append("</script>");4344this.Page.ClientScript.RegisterStartupScript(this.GetType(),"LV_" +this.ClientID, script.ToString());45 }46 }47}

I was having this problem too when working using the 'web application' model.

If your project is called 'AJAXEnabledWebApplication1', your service has the namespace 'WebService' and the method is 'HelloWorld()' then you need to reference it using the full project namespace even if the aspx file is in the same folder as the asmx file:

AJAXEnabledWebApplication1.WebService.HelloWorld()

Annoyingly it works as expected (ie simply WebService.HelloWorld() works) when using the 'web site' model.

Any idea why this is the case?

Have fun
Finn


Ok, another problem I see is that you're using Page.ClientScript, which I believe is deprecated. The current way to make the reference should be:

ScriptManager sm = ScriptManager.GetCurrent(Page);ScriptReference script =new ScriptReference(pathToScript);sm.Scripts.Add(script);ServiceReference service =new ServiceReference(pathToService);sm.Services.Add(service);

For dnamically built js (sctrings like you have) it should be done w/ the static members of ScriptManager, eg.:

ScriptManager.RegisterClientScriptBlock(Page, type, key, script, addTags);

Hope that helps...


I am using a WebApplication project. I changed the code to use the ScriptManager instead. Still getting the same error. How do you figure out what the namespace should be for the webservice? Maybe I am doing that part wrong?

I don't actually see where you're calling the webservice at all, now that I'm looking at your js. As an aside, you really should use an embedded resource file instead of hardcoding the js like that, it' makes it a lto easier to debug and maintain.

Anyway, in theory your call should look something like this:

JSM.OpenFrame.WebServices.LiveValidator.ValidateEmailAddress(args,OnSuccess);where OnSuccessis another javascript function that fires off when that webservice returns without an errror.

I acutally am using embedded resources, those few lines just create the object (the real code is in the resource). That is what my call looks like. By the way, the full error message is "JSM is not defined" so its not even getting anywhere in the namespace...

If you take a look at the javascript returned from the webservice the first line will look something like this:

Type.registerNamespace('AJAXEnabledWebApplication1');

Try tagging AJAXEnabledWebApplication1. (ie the project root namespace that's trying to be registered by the JS) at the start of your function's namespace.

As the namespace registration works in a web project but not a web application I'm wondering what I'm missing here - or is it a bug?


Have fun
Finn


Ok, it is working now. Turns out I also had a compile error in the WebService (UGH). Even if I did not, it would not have worked since I did not marked the WS with [ScriptService]. Thanks for all the help, I am good to go...for now.

No comments:

Post a Comment