Showing posts with label ajax. Show all posts
Showing posts with label ajax. Show all posts

Monday, January 19, 2009

Ajax Issue: "The history state must be small enough to not make the url larger than 1024"

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/ajax_issue_the_history_state_must_be_small_enough_to_not_m.htm]

I got a really weird Ajax bug the other day. I was working on an ASP.Net website and got this cryptic error whenever clicking a postbacking button within an Ajax update panel.

Microsoft JScript runtime error: Sys.InvalidOperationException: The history state must be small enough to not make the url larger than 1024

Then, re-clicking a tab, you get another ajax error:

Microsoft JScript runtime error: Object doesn't support this property or method
At this line:

if (element.tagName && (element.tagName.toUpperCase() === "SCRIPT"))

In this specific case, the element tag didn't have the toUpperCase() method. It had worked before, everything seemed strange. To make a long story short, it appeared to be a problem from installing VS SP1.  We had installed the old Ajax toolkit. The new SP updated the System.Web.Extensions.dll assembly in the GAC, which created different script resource files.
 

Old (which worked)New (which did not work)
  • Assembly Ver: 3.5.0.0
  • File Version: 3.5.21022.8
  • C:\MyProject\System.Web.Extensions.dll
  • Assembly ver: 3.5.0.0
  • File Version: 3.5.30729.1
  • C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Web.Extensions.dll


It worked on some machines and not on others because some machines had SP1 installed, and others did not. The new version is installed in the GAC, so the web app would always reference the new one. Note that both had the exact same credentials (like assembly version= 3.5.0.0), but different file versions.
 

Eventually, to get things working, we just uninstalled the new one from the GAC. (I guess if we had sufficient time, we'd see how to make the app play nice with the new DLL).  However, this was tricky because we couldn't just do a normal windows uninstall. Running:

Gacutil /uf System.Web.Extensions

Will return:

Assembly could not be uninstalled because it is required by Windows Installer
Number of assemblies uninstalled = 1
Number of failures = 0

This blog explained that that’s essentially a bug, and we can fix it from the registry.

http://blogs.msdn.com/alanshi/archive/2003/12/10/42690.aspx


Go to registry, for this key:

[HKLM\SOFTWARE\Classes\Installer\Assemblies\Global]
for this item:

System.Web.Extensions,version="3.5.0.0",publicKeyToken="31bf3856ad364e35",

processorArchitecture="MSIL",fileVersion="3.5.30729.1",culture="neutral"

and remove its data, so that in the "Edit multi-string" dialogue box, the "Value data" textbox is empty.

Now, you can remove form the GAC by running:

Gacutil /uf System.Web.Extensions

And confirm removal:

Gacutil /l System.Web.Extensions

NOTE – you may need to copy the System.Web.Extensions to your web’s bin folder and recompile the solution in VS.


Lastly, to make all the other websites still work, re-install the old dll:

gacutil /i C:\MyProject\System.Web.Extensions.dll

You should now be able to hit postbacks within Ajax update panels without errors.

Sunday, August 5, 2007

Migrating legacy apps to Asp.net AJAX

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/migrating_legacy_apps_to_aspnet_ajax.htm]

We've all heard how awesome Ajax is, so the practical question is how do I start using it? It's easy enough if you're building an app from scratch, but it's always harder when migrating a legacy app. Here are some things I've discovered while trying to migrate a 4-year ASP 2.0 web app (which was itself migrated from .Net 1.1).

 

Step 1: Update the web.config. Because a legacy app probably already has a big config, you'll need to merge sections in. While you can get the full web.config file from creating a new Ajax app, I've copied it here for convenience and greyed out the nodes likely to already exist. The relevant sections are

  • configSection.sectionGroup

  • page.controls

  • compilation.assemblies

  • httpHandlers

  • httpModules

  • system.web.extensions

  • system.webServer

xml version="1.0"?>
<configuration>
    <configSections>

        <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
                <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
                <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
                    <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere"/>
                    <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
                    <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
                sectionGroup>
            sectionGroup>
        sectionGroup>
    configSections>
    <system.web>
        <pages>
            <controls>

                <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            controls>
        pages>

       
        <compilation debug="true">
            <assemblies>

                <add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            assemblies>
        compilation>
        <httpHandlers>

            <remove verb="*" path="*.asmx"/>
            <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            <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"/>
            <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"/>
        httpHandlers>
        <httpModules>

            <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        httpModules>
    system.web>

    <system.web.extensions>
        <scripting>
            <webServices>
               
               
               
               
               
               
            webServices>
           
        scripting>
    system.web.extensions>
    <system.webServer>
        <validation validateIntegratedModeConfiguration="false"/>
        <modules>
            <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        modules>
        <handlers>
            <remove name="WebServiceHandlerFactory-Integrated"/>
            <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"/>
            <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"/>
            <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"/>
        handlers>
    system.webServer>
configuration
>

 

 

Step 1b. Beware of the web.config node: <xhtmlConformance mode="Legacy" />. This is inserted by the ASP.Net 1.1 to 2.0 migration. Setting this to legacy will mess up the HTML output that Ajax needs. ScottGu explains more here. If you have this node, you'll want to set it to "Transitional", however that could likely break a lot of your javascript. Note that as an intermediate step, you can still switch this node to "Transitional" in preparation for migrating to Ajax sometime in the future.

 

Step 2: Ensure that the System.Web.Extensions assembly is correctly referenced by your app. The MS Ajax download installs this in the GAC. You may need to copy it locally depending on how your application deploys.

 

 

It's really that easy. I was concerned that there would be some nuance - you'd need to modify some hidden file in a hidden folder, each page would need tweaking, or it just wouldn't work. I was pleasantly surprised how easy it was to migrate.

 

Once you have an ASP.Net Ajax app, then you can start using all the wonderful AJAX things like the amazing update panel, or the Ajax controls.

 


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.