October 2010 - Posts

Just Where Is WebResource.axd?
28 October 10 10:25 PM | Scott Mitchell | 7 comment(s)

I stumbled upon and answered a question at Stackoverflow this morning – Where is WebResource.axd? – and thought it might be worth to elaborate a bit on the question and answer here, on my blog.

But first, imagine you are developing a Web control or a library or a framework that requires certain external resources, such as images, JavaScript, and CSS. When developing your control/library/framework you may have such external content sitting in a particular folder in your application, but when you get ready to package your control/library/framework you want the end product to be a single assembly (that is, a single DLL file), and not an assembly plus a folder for images and a folder for JavaScript files and a folder for CSS files. In other words, you do not want to require that your users – other web developers – have to add a bunch of folders and images/JavaScript/CSS files to their website to start using your control/library/product; rather, you want everything to work once the developer drops your assembly into their Bin folder.

Such functionality is possible by using embedding resources. An embedded resource is a resource file – like an image, JavaScript, or CSS file – that is embedded within the compiled assembly. This allows a control/library/framework developer to embed any external resources into the assembly, thereby having the entire application existing in one single file. Consider ASP.NET’s validation controls. These controls require that certain JavaScript functions be present in order for them to use client-side validation. When using the validation controls you don’t need to add any JavaScript files to your website; instead, the JavaScript used by these controls is embedded in one of the built-in ASP.NET assemblies. But if the external resources are embedded in the assembly, how do you get it out of the assembly and onto a web page?

The answer is WebResource.axd. WebResource.axd is an HTTP Handler that is part of the .NET Framework that does one thing and one thing only – it is tasked with getting an embedded resource out of a DLL and returning its content. What DLL to go to and what embedded resource to take are specified through the querystring. For instance, a request to www.yoursite.com/WebResource.axd?d=EqSMS…&t=63421… might return a particular snippet of JavaScript embedded in a particular assembly. The d querystring parameter contains encrypted information that specifies the assembly and resource to return; the t querystring parameter is a timestamp and is used to only allow requests to that resource using that URL for a certain window of time.

To see WebResource.axd in action, create an ASP.NET Web page that includes some validation controls, visit the page in a browser, and then do a View/Source. You will see a number of <script> tags pulling in JavaScript from WebResource.axd like so:

<script src="/YourSite/WebResource.axd?d=fs7zUa...&amp;t=6342..." type="text/javascript"></script>

<script src="/YourSite/WebResource.axd?d=EqSMSn...&amp;t=6342..." type="text/javascript"></script>

Here, WebResource.axd is pulling out embedded JavaScript from an assembly and returning that JavaScript to the browser. If you plug in those URLs into your browser’s Address bar you’ll see the precise JavaScript returned.

Ok, so now that we know what WebResource.axd is and what it does the next question is, where is it? Clearly, there’s no file named WebResource.axd in your website – what’s going on here? Here’s my answer from the Stackoverflow question:

.axd files are typically implemented as HTTP Handlers. They don't exist as an ASP.NET web page, but rather as a class that implements the IHttpHandler interface. If you look in the root Web.config (%WINDIR%\Microsoft.NET\Framework\version\Config\Web.config) you'll find the following entry:

<add path="WebResource.axd" 
     verb="GET" 
     type="System.Web.Handlers.AssemblyResourceLoader" 
     validate="True" />

This entry says, "Hey, if a request comes in for WebResource.axd then use the HTTP Handler AssemblyResourceLoader in the System.Web.Handlers namespace.

The code for this class is a bit lengthy, so I can't post it here, but you can use a disassembler like the free Reflector to view this class's source code. You could probably get the original source code (with comments) by using the NetMassDownloader tool.

So there you have it. WebResource.axd is an HTTP Handler built into the .NET Framework that retrieves embedded resources from assemblies.

To learn more about WebResource.axd and how to go about embedding resources in an assembly, refer to my article, Accessing Embedded Resources through a URL using WebResource.axd.

Happy Programming!

Filed under:
Returning Dynamic Types from an Ajax Web Service Using C# 4.0
26 October 10 06:40 AM | Scott Mitchell | 4 comment(s)

Over at 4Guys I’m authoring a series of articles showing different techniques for accessing server-side data from client script. The most recent installment (Part 2) shows how to provide server-side data through the use of an Ajax Web Service and how to consume that data using either a proxy class created by the ASP.NET Ajax Library or by communicating with the Ajax Web Service directly using jQuery.

When returning data from a service it’s not uncommon to create a specialized Data Transfer Object (or DTO), and in Part 2 I create two such DTO classes. Here’s the basic design pattern:

  1. Create a DTO class that has properties that model the data you wan to return. For instance, the following DTO class can be used to transmit CategoryID, CategoryName, and Description information about one or more categories.
  2. public class CategoryDTO
    {
        public int CategoryID { get; set; }
        public string CategoryName { get; set; }
        public string Description { get; set; }
    }
  3. In the service, get the data of interest from your object layer. In the demo for this article series I use Linq-To-Sql as my data access layer and object model. Here is code from the Ajax Web Service’s GetCategories method that retrieves information about the categories in the system:
  4. [WebMethod]
    public CategoryDTO[] GetCategories()
    {
        using (var dbContext = new NorthwindDataContext())
        {
            var results = from category in dbContext.Categories
                            orderby category.CategoryName
                            select category;
    
            ...
        }
    }
  5. Now the results need to be mapped from the domain object to the DTO. This can be done manually or by using a library like AutoMapper. In the above example, we would iterate through the results to create an array of CategoryDTO objects, which is what would be returned.

If you are using C# 4.0 you can choose to live in a looser-typed world. Rather than having the Ajax Web Service return a strongly-typed value (namely, an array of CategoryDTO objects) you could instead opt to have a more ethereal return type – dynamic! Having a return type of dynamic allows you to return an anonymous type, meaning you don’t need to create a DTO nor do you need to map the domain object to the DTO. Instead, you’d just create an anonymous type, like so:

[WebMethod]
public dynamic GetCategories()
{
    using (var dbContext = new NorthwindDataContext())
    {
        var results = from category in dbContext.Categories
                        orderby category.CategoryName
                        select new
                        {
                            category.CategoryID,
                            category.CategoryName,
                            category.Description
                        };

        return results.ToArray();
    }
}

Note the dynamic keyword as the method’s return type. Also note that results is a query that returns an enumeration of anonymous types, each of which has three properties – CategoryID, CategoryName, and Description. The call to the ToArray method executes the query and returns the array of anonymous types as the method’s output. Because the anonymous type’s properties. The client-side script calling this method can work with the returned anonymous type using the exact same code as with the strongly-typed return type.

Happy Programming!

More Posts

Archives

My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.