Project Description

A simple, sample architecture for those .NET developers who want to use Adobe Flex as their RIA client instead of Silverlight. Provides a simple AMF Processor for communicating with Flex using your .NET objects in a non-obtrusive way.

Yes, I know, there are already several ways for your Flash/Flex components to talk to .NET (FluorineFX, WebOrb, BlazeDS, Adobe products, Red5, etc.) and the last thing we all need is another product to learn. But, when I first started out developing my Flex applications there weren't as many options (Adobe also had not released the official AMF specification), and the options that did exist had a pretty big impact on how my website project would be structured (page object inheritance, Http modules injected into my processing queue, object structures, lot of configuration to do mapping between server and client types, etc.). Not to mention, a lot of the solutions were Java based and I didn't want to go down that path.

I already had a large web site application that I wanted to add a Flex component to, and I didn't want to have to inject another HttpModule or any other structural requirements into my existing application. I just wanted a simple way for my Flex component to call into my ASP.NET back-end and utilize a lot of code I already had, including the ability to deal with objects on the server and client side in the same way (types, etc).

As a result, over time I developed what I feel is a simple component for dealing with Flex/Flash to .NET communication that can be used in your ASP.NET applications and other .NET applications without dictating how you structure your site or application. In addition, it is simple enough that you can build a much more complicated architecture on top of it using HttpModules or you can just use it on 1 web page or 1 web service. It doesn't require any configuration and uses custom attributes to tell the processor how to serialize/deserialize your .NET objects in AMF format (very similar to the way you can customize Xml serialization/deserialization in .NET).

Examples

Using the component in an ASP.NET web page

In this example, let's assume you have a web page (FlexHandler.aspx) that handles a couple of requests that return the appropriate object to your Flash/Flex client. Since no actual HTML output will be generated for this page, the .aspx looks like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="FlexHandler.aspx.cs" Inherits="FlexHandler" %>

The code behind is where we actually do our processing. In this case, depending on the command requested we process the input parameters and return the appropriate object:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.UI;
using Kamacho.DNF.AMF;
using System.Threading;

public partial class FlexHandler : System.Web.UI.Page
{
    //reference to our processor
    private AMFProcessor _processor;

    protected void Page_Load(object sender, EventArgs e)
    {
        //initialize the processor to handle the HttpRequest as the input stream
        //and the HttpResponse as the output stream
        _processor = new AMFProcessor(this.Request, this.Response);

        //sets the event handler that will process the incoming requests
        _processor.Command += new AMFProcessor.AMFCommandHandler(_processor_Command);
        
        //tells the processor to handle the request and output the results to the 
        //HttpResponse object
        _processor.ProcessHttpRequest();
    }

    //is called by the AMFProcessor when it is ready to receive an output value
    //for a request from the client
    void _processor_Command(AMFClientRequest request)
    {
        switch (request.Command)
        {
            case "LoadProfile":
                LoadProfile(request);
                break;
            case "LoadInvoice":
                LoadInvoiceForUser(request);
                break;
        }
    }

    //example of returning a typed object
    private void LoadProfile(AMFClientRequest request)
    {
        //get the profile id from the parameters sent in by the client
        string profileId = request.GetString(0);

        //normally you would call some component to load a profile object
        //but in this case we will just initialize one
        ProfileDTO profile = new ProfileDTO();
        profile.Id = profileId;
        profile.Name = "Sample User";
        profile.Email = "suser@samples.com";

        //set the response object to our DTO so we can use it on the client
        request.Response = profile;
    }

    //example of returning a generic action script object
    private void LoadInvoiceForUser(AMFClientRequest request)
    {
        //get the current user id, since this page is in our normal ASP.NET application
        //we have access to anything in our normal AppDomain, including our security 
        //whether we are using Cookies, Sessions, etc....
        //this way we let our security mechanism handle user params and identity instead
        //of passing user id as a parameter on the wire
        string userId = Thread.CurrentPrincipal.Identity.Name;

        //create a generic action script container to return the profile of the current
        //user and the invoice requested
        ActionScriptObject aso = new ActionScriptObject();

        //again, normally you would be loading these up from another component
        ProfileDTO userProfile = new ProfileDTO();
        userProfile.Id = userId;
        userProfile.Name = "Current User";
        userProfile.Email = "someuser@samples.com";

        //add it to the action script object
        aso.AddProperty("user", AMFDataType.AMFEnabledObject, userProfile);

        //load up an invoice
        InvoiceDTO invoice = new InvoiceDTO();
        invoice.Id = Guid.NewGuid();

        //add it to the action script object
        aso.AddProperty("invoice", AMFDataType.AMFEnabledObject, invoice); 

        //add specific properties also
        aso.AddProperty("loaded", AMFDataType.Boolean, true);

        //set the response object
        request.Response = aso;
    }
}

See the Documentation for more in depth examples, a sample website application is provided in the download so you can see the various ways to use this component toolkit

Last edited Jan 10, 2009 at 4:13 AM by Kamacho122, version 12