Where were we?
In my previous posts about MS AJAX Extensions I talked about the additions to the web.config, Serialization, proxy generation, and ScriptHandlerFactory, that is the factory that handles *.asmx requests and *_AppService.axd requests. To refresh memory, what the ScriptHandlerFactory does is to check if the request has application/json ContentType (a REST method request) or the request path ends with /js or /jsdebug (a REST client proxy request). If it is a REST method request (http://localhost/AJAXServerSide1/AjaxWebService.asmx/GetModifiedUser), it gets the web service data, calls the requested method and returns the result. If it is a REST client proxy request (http://localhost/AJAXServerSide1/AjaxWebService.asmx/js), it returns the generated client proxy. If it isn’t a REST method request or a REST client proxy request, it delegates the request to the “normal” *.asmx HttpHandler.
The HttpHandler for *_AppService.axd exists to allow the developer to use some application services with AJAX. The only available application services available in v1.0 are Profile_JSON_AppService.axd and Authentication_JSON_AppService.axd. The profile service exposes the methods:
The authentication service exposes the following methods:
To use the services, we have to enable them in the web.config. For the profile service, we have to set the properties that can be read and write by MS AJAX. For the authentication service we can specify if it requires SSL or not.
There is a role service that exposes the method GetRolesForUser but it isn’t enabled in the current version.
The default implementation of the services can be changed, but I won’t be touching that until we study the ScriptManager.
The last HttpHandler that MS AJAX adds to the web.config is the ScriptResourceHandler, for the path ScriptResource.axd. Lets study it in more detail…
ScriptResourceHandler in detail
The main function performed by the ScriptResourceHandler is to load scripts from resources stored in the assembly and adding localized resources to the scripts.
A request to the ScriptResource.axd must be done at the root level for the application (~/ScriptResource.axd). The request has the information needed to process it encrypted in the query string (the encryption and decryption process is done using the EncryptString and DecryptString methods of the System.Web.UI.Page class). The decrypted format for the query string is:
“d=” + 1 character that indicates additional processing + assembly name + ‘|’ + resource name + ‘|’ + cultureName.
The first character can be ‘u’, ‘U’, ‘z’ or ‘Z’. An uppercase character indicates that the feature is enabled and the lowercase character indicates that the feature is disabled. The ‘Z’ indicates that the resource has to be compressed (using GZip). The ‘U’ indicates to add some code to the end of the script, to notify the MS AJAX runtime that script has been loaded. The code that gets added to the script is:
The assembly name and the resource name must be specified. If not, an error 404 (page not found) will be returned. The culture name is used to set the CurrentThead.CurrentUICulture property. If no culture is specified, the invariant culture is used.
To expose resources stored in an assembly, the assembly level attributes ScriptResourceAttribute and WebResourceAttribute have to be used.
The ScriptResourceAttribute has 3 important properties: ScriptName, ScriptResourceName and TypeName. The ScriptName property will be compared to the requested resource name. ScriptResourceName points to a resource file that contains strings. The TypeName property specifies a script type that will be created containing the localized strings (of the CurrentUICulture, or the default ones if no CurrentUICulture specific resources exist) present in the resource specified by ScriptResourceName.
The WebResourceAttribute has 3 important properties: WebResource, ContentType and PerformSubstitution. The WebResource property will be compared to the requested resource. ContentType specifies the type of data stored in the resource and will be used to write the ContentType for the response. The PerformSubstitution property is used by the ScriptResourceHandler in order to convert expressions like:
<%= WebResource("MyResources.JScript2.js") %> or <%= ScriptResource("MyResources.JScript2.js") %>
To the URL of the resource. If WebResource is used, the generated URL will start with “WebResource.axd?d=”. For ScriptResource, the generated URL will start with “ScriptResource.axd?d=”. The substitution is performed using regular expressions.
When a resource that ends with .debug.js is requested, the release mode resource (resource name that ends with .js) is also requested. At least one of those resources has to exist.
If we have set the property EnableCaching for the ScriptResourceHandler in the configuration section, the response will be cached using the ASP.NET output cache by the server for a year.
The response will be generated in 3 steps:
• The requested resource will be read using the GetManifestResourceStream method from the Assembly class. If PerformSubstitution is enabled, the substitution explained above is performed.
• If the ScriptResourceAttribute is used, a ResourceManager for the resource file with the localized resources is obtained, and some script is added to save the resources (see the code below)
• If the MS AJAX runtime has to be notified of the loading of the script, add the script line shown above.
If we have the following assembly level attributes:
[assembly: ScriptResource("MyResources.JScript1.js", "MyResources.MyStrings", "MyResources.Res")]
The file MyResources.JScript1.js is like this:
<%= WebResource("MyResources.JScript2.js") %>
The file MyStrings.resx has the string named String1 = “This is a test”, when the resource “MyResources.JScript1.js” is requested, the response content is:
"String1":"This is a test!"
If you add another resource file to localize the resources for spanish (MyStrings.es-ES.resx) and configure the application to use the Spanish UI culture, the response for the resource “MyResources.JScript1.js” is:
"String1":"¡Esto es una prueba!"
That's all for now. In a next post I'll finally finish explaining all the elements present in the web.config for an asp.net ajax application.