Build your own modded System.Web.Extensions.dll
Earlier today Microsoft released the source code to the AJAX 1.0 release System.Web.Extensions library. I was in the apparently unique position of needing to modify parts of the code for a special case application, so I downloaded the source right away ready to modify, compile and deploy.
I guess I was pretty naive to think that it would be that easy. The distribution doesn’t include some pretty important parts. A .csproj file for one. The entire Resources class for another.
So I had to work my way through the process of getting a compile-able version of the library ready to replace the official System.Web.Extensions binary in my project. The server code Reference License prevents me from simply providing the project to you, but here are the high points if you need to do the same.
Be aware:
This is neither easy nor straightforward and I probably forgot a few steps when I was writing this. You’re gonna have to be diligent to get it to work, even with this howto.
Getting Started
1) Download and install the source
2) Create a new C# project in Visual Studio. You can call it whatever you want but I would suggest you avoid using the same namespace because the System.Web namespace is strongly named and exists in several assemblies. I called mine Dave.Web.Ajax
3) Copy all the files and folders from the source installed directory (C:Program Files (x86)Microsoft ASP.NETASP.NET 2.0 AJAX Extensionsv1.0.61025SourceSystem.Web.Extensions on my computer) into your new project directory and include them in the project.
4) Make sure your Default Namespace on the project is something good – again Dave.Web.Ajax in my case.
Get the Missing Files
1) Start the .Net Reflector (if you’re a serious .Net developer, you should have downloaded this to your computer long ago, btw)
2) Open the official System.Web.Extensions.dll file
3) Save all the Resources into a new Resources folder in your project. When you save them, drop the “System.Web.Resources” part of the filename if it’s there.
4) You should now have a file called AtlasWeb.resources in your folder
5) Open a VS Command Prompt and in your resources folder run
resgen AtlasWeb.resources AtlasWeb.resx. This will generate the resx file that you need in visual studio to dynamically generate the class.
Setup your Embedded Resources
1) In VS, include all the files in the Resources in your project (except the *.resources files) if you haven’t already.
2) Select them all and set the Build Action to Embedded Resource
3) Click on the AtlasWeb.resx file and set the Custom Tool property to “ResXFileCodeGenerator”. This will generate the AtlasWeb.Designer.cs file which gives you a real class with properties for each item in the resource file.
NOTE) You might need to repeat this process (and the resgen.exe process) for the other *.resources files, but I haven’t done it and havn’t had any issues yet.
Rename the Namespace and cleanup
If you are going to stick with using the System.Web.* namespace, then you can skip this step.
1) Basically, I handled this in an iterative fashion. I did a project Find-and-Replace for “System.Web.” and replaced with “Dave.Web.Ajax.” Of course this process will break stuff because now objects that are really in the System.Web namespace (and not in the System.Web.Extensions assembly) will dissappear.
2) Get your iteration on: compile, add “using System.Web.something;” to a file with the error, compile, repeat.
Fix the Embedded Resource references
At this point, your project should compile and if you reference it in a web project in place of the System.Web.Extensions.dll file (or the GAC reference) the web project should compile too. But as soon as you load up a page with AJAX controls on it, you will get a runtime error saying the Resource File could not be found.
Update the reference names of your embedded .js files to be fully qualified. Your new fully qualified resource name will be “DefaultNamespace.Resources.Filename.js” Mine is “Dave.Web.Ajax.Resources.MicrosoftAjax.js” for example.
There are references in these files
UIScriptManager.cs:931,935
UIWebResourceUtil.cs:64+
UITimer.cs:147
Update those references to use the fully qualified names. After that, in WebResourceUtil.cs there is an optimization in the SystemWebExtensionsContainsWebResource(string) function that you have to modify. It does a switch statement on the length of the input string before comparing to the resource name string. Update each case conditional to be the length of the string in that case statement. If you forget this step you will be very confused why it says it can’t find a resource that you know is there…
Now, all embedded resources need an assembly reference so that they can be detected using reflection (which is how the AJAX library looks for a valid embedded resource). I just created a dummy class called Scripts.cs inside the Resources file so I could include the assembly attributes:
[assembly: System.Web.UI.WebResource("Dave.Web.Ajax.Resources.MicrosoftAjax.debug.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Dave.Web.Ajax.Resources.MicrosoftAjax.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Dave.Web.Ajax.Resources.MicrosoftAjaxTimer.debug.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Dave.Web.Ajax.Resources.MicrosoftAjaxTimer.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Dave.Web.Ajax.Resources.MicrosoftAjaxWebForms.debug.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("Dave.Web.Ajax.Resources.MicrosoftAjaxWebForms.js", "text/javascript")]
namespace Dave.Web.Ajax.Resources
{
class Scripts
{
}
}
Just make sure you have a WebResource attribute for each of the javascript files in the project.
That’s it
Assuming you’ve gotten this far, you must be dedicated or desperate. Now you can go in and make your mods to any of the AJAX files and you’re good to go. Hopefully this was helpful and I wish I could just post the project, but rules is rules.
Its been about 6 hours since I finished my conversion, so its pretty fresh in my head, but I may have forgotten a step somewhere. I’ll try to answer questions in the comments but I’m pretty busy these days and I just blew half my day because the release of AJAX doesn’t play well inside iframes (which is the whole reason I had to do this mod).
Good luck to you.
July 11th, 2010 at 1:00 am
I finally decided to drop a comment, and let me tell you this is another very strong and powerful post. I’ve been reading through some of your previous posts and have been visiting your blog every now and then. Take a look at Xbox Stealth ebook and let me know if it can help you with your xbox 360 and maybe help you learn how to finally burn games and play on xbox live safely!
Anyways, good luck on your blog, and feel free to check out : Xbox Stealth
Thanks so much!
All the best,
Dino Vedo
July 10th, 2010 at 5:20 pm
Excellent and very thoughtful post! I really appreciate the time and effort you put in every single one of your posts, and finally decided to drop a comment on one of them! If you got some extra time on your hands and looking to mod your xbox 360 and unlock its full potential, check out the xbox stealth ebook on modding your console.
Anyways, good luck on your blog, and feel free to check out : Xbox Stealth
Thanks so much!
All the best,
Dino Vedo
July 29th, 2008 at 5:04 pm
rere gfdg
sdfg
dfgdfg
fdgdfg
July 24th, 2007 at 2:31 pm
I’ve got a headache and blood is coming out my ears. lol
Thanks for the article this is going to take me some time to digest.
July 20th, 2007 at 5:24 pm
You can remove the need to change all of the Resource References to the fully qualified names if you change the <RootNamespace> tag in the project that you create to be blank. This will make the resources created by the project not have the namespace pre-pended. If you plan on the using the default System.Web.Extensions namespace then you shouldn’t have to make any code changes.
February 22nd, 2007 at 6:39 pm
One other thing on this, be aware that if you replace “system.web” with your own namespace there are also hardcoded references to configuration sections you will need to change that won’t break the build but will break at runtime…and that you will need to change all of the references to System.Web.Extensions in the web.config to your own version…
thanks for putting this out there!
January 31st, 2007 at 2:42 am
The client-side code and server-side code were released under seperate licenses. Client side was under the Permissive License which is great. The way Microsoft released the server source basically forces it to be for reference only (under the Reference License). By posting – essentially redistributing – a compileable version it would not be used for reference purposes, people would download it and use it in the their projects which would violate the “specifically excludes the right to distribute the software outside of your company” clause of the Reference License… but IANAL either. So that’s just my take.
January 31st, 2007 at 2:35 am
Thanks for posting it and being so informative – glad at least you found a resolution to the issues that you documented and followed-up on the other thread…
I may be incorrect – but there is nothing I believe that prohibits re-distribution or including a project download of it (project solution) – as it is for reference use. Further more – I am no lawyer however – the license does state as long as you are not using Microsoft’s name to promote it then you can pretty much do as what you wish and there is not an issue with modifying it redistributing as you see fit as long as you do not use any of Microsoft’s name, copyrights, logos etc…