Tech Blog

Jay's Technical blog

How To: Enable Microsoft ASP.NET Ajax Extension RC1 (and Dec. 2006 CTP) on an existing site

16 December 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

[Old article warning... you are probably looking for this.] 

[Here’s the latest update to my series of articles on enabling MS Ajax and the CTP in an existing site. Sorry, there are enough changes that we need a new article.  By the way I provide the differences between the last beta and the rc1]

Enabling Microsoft ASP.NET Ajax Extensions
As with the last time we need to make some edits to the Web.Config file.

Step 1
If you don’t already have a configSections section then add one right after the <configuration> tag; the top of your file should look like thisif you needed to add the configSections element:

<?xmlversion="1.0"?>
<configuration>
   <
configSections>
   </configSections>

Now right before the</configSections> tag add the following:

<sectionGroupname="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
  
<sectionGroupname="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
         <
sectionname="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false"/>
      <
sectionGroupname="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
         <
sectionname="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
         <
sectionname="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
         <
sectionname="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
      </
sectionGroup>
   </
sectionGroup>
</sectionGroup>

[The big changes between this one and the last beta is that the microsoft.web namespace is gone from the MS Ajax Extensions, so the system.web.extensions replaced the microsoft.web entry above, and there is a new entry called “scriptResourceHandler.”]

Step 2
Add the following lines inside the system.web section (this lets you use MS ASP.NET Ajax tags in pages without referencing the assembly in the page… I have given you the complete pages section, pay attention some third party tools also use this section… I would suggest adding this code and then re-adding the items from the third party tool back to the appropriate places):

<pages>
   <
controls>
     
<addtagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
controls>
   <
tagMapping>
      <
addtagType="System.Web.UI.WebControls.CompareValidator" mappedTagType="System.Web.UI.Compatibility.CompareValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.CustomValidator" mappedTagType="System.Web.UI.Compatibility.CustomValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.RangeValidator" mappedTagType="System.Web.UI.Compatibility.RangeValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.RegularExpressionValidator" mappedTagType="System.Web.UI.Compatibility.RegularExpressionValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.RequiredFieldValidator" mappedTagType="System.Web.UI.Compatibility.RequiredFieldValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.ValidationSummary" mappedTagType="System.Web.UI.Compatibility.ValidationSummary, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
tagMapping>
</
pages>

[The big changes between this one and the last beta is that the “asp” tag prefix references the System.Web.UI instead of Microsoft.Web.UI namespace.  Also, there is only one entry in the controls node]

Step 3
In the assemblies section of the the compilation section within the system.web section (you may need to create close tags for compilation element as it usually doesn’t have any child tags).  Add the following lines (I’m giving you the complete compilation section… look closely at what you are overwriting… if you have child tags of compilation you may need to add them back in... Also if you are using something other than C# then remove the defaultLanguage="C#" from the compilation tag):

<compilationdebug="false">
  
<
assemblies>
      <
addassembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
assemblies>
</compilation>

[Only changes from the beta here is the obvious one… Microsoft.Web.Extensions is now System.Web.Extensions]

Step 4
Also in the system.web section, you also need to add some handlers to the httpHandlers section (I’ve shown you the complete httpHandlers section in case you don’t have one — you may only need the additional stuff between the httpHandlers tags.nodes):

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

[There are a bunch of changes here from the beta: the changing of the Microsoft.Web… namespace to System.Web… as well as the verb in the last add entry has changed to include HEAD requests as well as GET requests.]

Step 5
Also in the system.web section, you also need to add some modules to the httpModules section (I’ve shown you the complete httpModules section just like I did with the httpHandlers):

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

[Beyond the replacement of the Microsoft.Web… namespace to System.Web…  namespace, the httpcompression has been removed (very strange) ]

Step 6
Finally after the</system.web> element and before the last </configuration> element, add the following ASP.NET AJAX (only) code:

<system.web.extensions>
   <
scripting>
      <
webServices>
         <!--
Uncomment this line to customize maxJsonLength and add a custom converter-->
         <!--
        
<jsonSerialization maxJsonLength="500">
            <converters>
               <add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/>
            </converters>
         </jsonSerialization>
         -->
        
<!--Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate.-->
         <!--
        
<authenticationService enabled="true" requireSSL = "true|false"/>
         -->
        
<!--Uncomment these lines to enable the profile service. To allow profile properties to be retrieved 
                and modified in ASP.NET AJAX applications, you need to add each property name to the readAccessProperties and
                 writeAccessProperties attributes.
-->
         <!--
        
<profileService enabled="true"
                                 readAccessProperties="propertyname1,propertyname2"
                                 writeAccessProperties="propertyname1,propertyname2" />
         -->
     
</webServices>
      <!--
 
      <scriptResourceHandler enableCompression="true" enableCaching="true" />
      -->
  
</scripting>
</
system.web.extensions>

<system.webServer>
   <
validationvalidateIntegratedModeConfiguration="false"/>
   <
modules>
      <
addname="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
modules>
   <
handlers>
      <
removename="WebServiceHandlerFactory-ISAPI-2.0"/>
      <
addname="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
              type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addname="ScriptResource" verb="GET" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
   </
handlers>
</
system.webServer>

[So here’s what is different between the RC1 and beta2.  The microsoft.web node has changed to system.web.extensions.  The “ScriptModule” module added to the modules section uses the System.Web… namespace, and the ScriptHandlerFactory and the ScriptResource handlers added to the handlers section also uses the System.Web… namespace.]

Since the Microsoft.Web.Extensions.dll is installed in the GAC you won’t need to reference any DLLs and you are all set to use the ASP.NET Ajax Extensions…

[begin Shameless Blogger plug of his employer]

ASPSOFt Logo
Your ASP.NET Ajax experts

[end Shameless Blogger plug of his employer]

One of the first things you will notice is if you used Atlas at all is that there are a number of missing components.  Where did they all go? Simple, there was too much work to get it all done soon, so they split Atlas into 2 projects.  One that delivers the most popular components (the ScriptManager and the UpdatePanel, mainly), and one that delivers everything else.  So how do we enable the rest of the components.

Enabling Microsoft ASP.NET Ajax CTP (future technology) on an existing site
The first step is to go through all the steps in enabling the ASP.NET Ajax Extensions.

Now in the controls section withinthe pages section inthe system.web section (see step 2 above) add the following lines:

<addtagPrefix="asp" namespace="Microsoft.Web.Preview.UI" assembly="Microsoft.Web.Preview"/>
<
addtagPrefix="asp" namespace="Microsoft.Web.Preview.UI.Controls" assembly="Microsoft.Web.Preview"/>

[There are no changes in these nodes]

The complete pages section will look like this (if you didn’t need to customize it as a result of some other tool/library):

<pages>
   <
controls>
      <
addtagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagPrefix="asp" namespace="Microsoft.Web.Preview.UI" assembly="Microsoft.Web.Preview"/>
      <
addtagPrefix="asp" namespace="Microsoft.Web.Preview.UI.Controls" assembly="Microsoft.Web.Preview"/>
   </
controls>
   <
tagMapping>
      <
addtagType="System.Web.UI.WebControls.CompareValidator" mappedTagType="System.Web.UI.Compatibility.CompareValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.CustomValidator" mappedTagType="System.Web.UI.Compatibility.CustomValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.RangeValidator" mappedTagType="System.Web.UI.Compatibility.RangeValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.RegularExpressionValidator" mappedTagType="System.Web.UI.Compatibility.RegularExpressionValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.RequiredFieldValidator" mappedTagType="System.Web.UI.Compatibility.RequiredFieldValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addtagType="System.Web.UI.WebControls.ValidationSummary" mappedTagType="System.Web.UI.Compatibility.ValidationSummary, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
tagMapping>
</
pages>

[At this point the original text ends, but there are more changes with the December 2006 CTP]

Add the following code to the compilation section underneath the system.web section (after the “</assemblies>” but before the “</compilation>”):

<buildProviders>
  
<addextension="*.asbx" type="Microsoft.Web.Preview.Services.BridgeBuildProvider"/>
</
buildProviders>

The complete compilation section looks like this:

<compilationdebug="false">
   <
assemblies>
      <
addassembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
assemblies>
   <
buildProviders>
      <
addextension="*.asbx" type="Microsoft.Web.Preview.Services.BridgeBuildProvider"/>
   </
buildProviders>
</
compilation>

Add the following http handler to the httpHandlers section:
<addverb="GET,HEAD,POST" path="*.asbx" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>

The complete httpHandlers section looks like this:

<
httpHandlers>
   <
removeverb="*" path="*.asmx"/>
   <
addverb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   <
addverb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
   <
addverb="GET,HEAD,POST" path="*.asbx" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
</
httpHandlers>

Finally, add the following httpHandlers handler to the section in the system.webServer section:

<addname="ASBXHandler" verb="GET,HEAD,POST" path="*.asbx" preCondition="integratedMode"
         type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

The complete the system.webServer section looks like this: 

<system.webServer>
   <
validationvalidateIntegratedModeConfiguration="false"/>
   <
modules>
      <
addname="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
modules>
   <
handlers>
      <
removename="WebServiceHandlerFactory-ISAPI-2.0"/>
      <
addname="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
              type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      <
addname="ScriptResource" verb="GET" path="ScriptResource.axd" 
              
type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      <
addname="ASBXHandler" verb="GET,HEAD,POST" path="*.asbx" preCondition="integratedMode"
              type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
   </
handlers>
</
system.webServer>


The final step here is to add a reference to the Microsoft.Web.Preview.dll assembly. 

[Final thoughts: It seems to me that these releases have majorly changed (again).  I need to play with the PageMethods stuff to see if anything has gotten better or worse there.  RC1 noticably has removed the httpCompression module (but Http Compression of script resources is still happening).  I’m also seeing a bunch of changes in the CTP which is to be expected (it is a CTP afterall).]

[tags:ASP.NET, AJAX, MS Ajax]

Land of the ORMs

12 December 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

As many of you know I have made some strong statements in the past regarding ORMs (in fact I’ve probably lost readers over it).  Recently in my day job, I was given two projects that I decided to use an ORM for (and I used different ones each time).  I used the writings of my fellow blogger, David Haydn, to help me settle on an ORM for each project.

Project #1 – CastleProject’s ActiveRecord with MS Access
Yes, you read that right.  I had to use Access with a fairly small web project (this was the client’s spec not mine).  So as I looked around I saw that there was a driver for the Castle Project’s ActiveRecord to use MS Access.  Development went fairly smooth although not necessarily any faster than when I use CodeSmith to generate a DAL (although admittedly, I was still learning the Framework a little).  At the end I did have to do a marathon run of replacing Castle’s ActiveRecord due to Medium (with some custom changes to allow Access via OLEDB) security in a hosted environment… The punch line is that this would have worked, but only the web site could use OLEDB (any assemblies that one was using were not trusted enough to do OLEDB).  All in all it wasn’t a horrible experience.  I would use Castle ActiveRecord again, but I won’t be going out of my way to do so.  I didn’t feel that it bought me much (yeah, being able to query via code is cool… even if you are writing SQL dynamically <wink />)

Project #2 – ActionPack/SubSonic with MS SQL
I had seen a number of people raving about what a time saver this one was as well as the power it gives you.  After watching the 10 minute video of it I was sold.  This was the 1 ORM I could probably use at the corporation where Stored Procs were the only legitimate method for accessing a table.  While I am still on the fence over the generation of SQL statements at runtime, this is the project that might convince me.  The project is not completely done, but I have been able to do quite a bit with a full set of tools.  What I haven’t been able to accomplish with the ORM I have been able to easily substitute in Stored Procs (and use them easily).  I’m using the CodeGen method so I can generate my base ORM/DAL classes and then I have a separate project where I have extended these classes.  I’ve had a couple issues that a recent code refresh has helped me with.  The only weird thing I have really had to do was recompile their source code to get rid of the MySQL driver (since I’m not using that and am not so sure what my boss would say if he saw it in the bin directory of the site).  This has been an awesome experience, and I’m thinking of scrapping my CodeSmith templates because this provides everything that my CodeSmith templates provide me, and provides so much more than what I’m already doing (for instance all collections can accept a DataReader as a parameter for populating the collection; the storedprocs class provides a way to easily execute a storedproc and get a reader; being able to throw together a quick query without having to launch the SQL Server tools has also come in handy… I’m impressed to say the least).  This tool may have converted me…

 [tags: ASP.NET, ORM, SQL Server, C#]


Script#!!!!! (new release)

07 December 2006
Jay Kimble

[WARNING! This is an archived post and as such there may be things broken/missing here.. you have been warned.]

I hope I don’t upset Nikhil Kothari off (unless I missed his announcement), but I was on his projects site today and noticed that he’s updated Script# (the Ajax toolkit I have been having the most fun with lately).

The new release appears to include support for WPF/E, .aspx code-behind, the “Atlas” type-system, and an installer…

If you haven’t played with it before let me explain what it is.  Script# is a toolkit that let’s you write C# code and have it “compiled” into javascript.  Now, if you are like me that sounds like a horrible idea (isolating the programmer from the underlying language… especially when it seems that you are moving to a higher level language).  The truth is that Nikhil has provided a number of cool things that you will want.  For instance there are 2 types of projects (at least in the last release).  The first type was good for building re-usable javascript libraries.  The second type of project was great for building the application glue that we all end up building to hook our apps with our re-usable scripts; this second type of project was kind of a combination or javascript and c# code, and when the javascript code is ultimately deployed it is deployed via a DLL which contains the javascript code as a resource that gets dropped to the end-user’s browser via webresources (automatically).  To make this last point work Nikhil includes an ASP.NET server tag that jumps starts the application.

He provided a custom library for manipulating the GUI from a Script# project, so it was pretty easy to write new UI libraries (more on that in a sec); if you know javascript already it actually is easy to transition to this and produce some very poweful results.  The resulting script file(s) ladies and gentlemen are READABLE!  In other words one of the goals of Script# is to have it produce clean looking Javascript that a human javascript programmer can read or modify.

I found that I could build a fairly complex solution without writing nearly as much code (comparing JS code to c# code).  Eventually I’ll post my project here.  I built a “fairly simple” html tree control… I say “fairly simple” because 1) the 2 C# classes I wrote to accomplish the control are not rocket science by any means (1 of them is a generic node, and the other is the tree container), 2) the html tree control doesn’t have a lot of features but it could easily to grow larger without a lot of effort (I’ll post the project sometime soon).

[tags: ASP.NET, Ajax, Script#, C#]