Project Description

The goal of Amf4asmx is to provide an easy, lightweight solution for flash to integrate with ASP.Net 2.0 using flash remoting (AMF) with as few changes as necessary to the original codebase, starting from an ASP.Net Web Service endpoint (asmx). Amf4asmx is comparable to AMFPHP.

In order to make Amf4asmx easier to use, we are not only making the setup process simple, but we also focus on the usability of the endpoint from the Flash developer's standpoint. Using flash remoting, Amf4asmx has full control over the types sent back to flash, and can therefore provide strongly-typed results; for example, Amf4asmx gives back true and false values rather than "true" or "false".

If you're looking for Flash Remoting for WCF - please check out WCF Flash Remoting.


In order to set up Amf4asmx, you need to:
  1. Create a standard WebService in ASP.Net with an asmx endpoint.
  2. Add the Amf4asmx binary to the Bin directory for your web application.
  3. Modify your web.config file:

		<section name="amf4asmx" type="Amf4Asmx.Configuration.ServiceHandlersSection, Amf4Asmx"/>
			<remove verb="*" path="*.asmx"/>
			<add verb="*" path="*.asmx" validate="false" type="Amf4Asmx.Web.Handlers.WebServiceHandlerFactory, Amf4Asmx"/>
	<amf4asmx defaultType="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
		<add contentType="application/x-amf" type="Amf4Asmx.Web.Handlers.AmfServiceHandler, Amf4Asmx" />

The defaultType attribute on the amf4asmx element is the old *.asmx httpHandler - for .NET 3.5's ScriptHandlerFactory, use: (shown above)
System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35

If you want to use the default ASP.Net 2.0 httpHandler when not using Amf, remove the defaultType attribute.


The following are samples that, when using Amf4asmx, result in a fully functioning flash remoting gateway.

Sample Web Service (C#)

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Services;
using System.Web.Services.Protocols;
namespace DemoWebService
    [WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1, Namespace="urn:Amf4Asmx")]
    [WebService(Namespace = "urn:Amf4Asmx")]
    public class HelloWorldService : WebService
#region Hello World Demo Method
        public string HelloWorld()
            return "Hello World";
#endregion Hello World Demo Method
#region Structures and Arrays Demo Method
        public struct NameList
            public string[] names;
        public NameList HelloWorldStruct(NameList list)
            List<string> result = new List<string>();
            for (int i = 0; i < list.names.Length; i++)
                result.Add(string.Format("Hello, {0}!", list.names[i]));
            return new NameList() { names = result.ToArray() };
#endregion Structures and Arrays Demo Method
#region Multiple return values Demo Method
        public int MultipleOut(out string name)
            name = "test";
            return 10;
#endregion Multiple return values Demo Method
#region Soap Header Demo Method
        public class TestHeader : SoapHeader
            public string Text { get; set; }
        public TestHeader SomeHeader { get; set; }
        [WebMethod, SoapHeader("SomeHeader", Direction = SoapHeaderDirection.In)]
        public string InputHeaderTest()
            return SomeHeader.Text;
#endregion Soap Header Demo Method

Sample ActionScript (AS2)

import mx.remoting.*;
import mx.remoting.debug.*;
import mx.rpc.*;
var svc:Service = new Service("http://localhost:1837/service.asmx"); // note that the service name is not required - Amf4asmx knows from the endpoint url what service you are referencing.
function handleSimpleReturn(re:ResultEvent) {
	trace("Got result of type "+typeof (re.result));
	trace("Got result \""+re.result+"\"");
function handleFault(fe:FaultEvent)
	trace("Fault: " + fe.fault.type + ", " + fe.fault.faultstring);
var list:Object = { names: new Array("Bob", "Joe", "Steve", "everyone") };
// this call demonstrates Amf4Asmx's direct support of custom Flash objects and Flash arrays.
var pc:PendingCall = svc.HelloWorldStruct(list);
pc.responder = new RelayResponder(this, 'handleHelloWorldStruct', 'handleFault');
function handleHelloWorldStruct(re:ResultEvent) {
	trace("Got type '"+typeof(re.result) + "'");
	trace("Got "+re.result.names.length+" names");
	for (i = 0; i < re.result.names.length; i++)
// this call demonstrates use of AmfHeaders acting as SoapHeaders without any additional code from either developer.
svc.connection.addHeader("SomeHeader", false, { Text : "My Text" });
svc.InputHeaderTest().responder = new RelayResponder(this, 'handleSimpleReturn', 'handleFault');
// this call intentionally results in a fault
svc.BadMethod().responder = new RelayResponder(this, 'handleSimpleReturn', 'handleFault');

Error Handling

Because Flash only responds to 200 OK results from the server, Amf4asmx must always return an HTTP success. However, additional unhandled exception EventHandlers have been provided:
Even if these exceptions are handled, a Fault message will be returned to the Flash Response object.

Last edited Oct 19, 2009 at 2:15 AM by mdekrey, version 14