Хитрость заключается в том, чтобы использовать FluorineFx.IO.AMFMessage
с AMFBody в качестве объекта результата и установить свойство Content
.
Вы можете увидеть это в прокси Чарльза с другими рабочими примерами (я использовал отличный Примеры WebORB , в частности Flash Remoting Basic Invocation AS3 )
Я обновил AMFFilter для поддержки Response
параметра, который необходим AMFBody.Возможно, это может быть решено более элегантно с помощью некоторого текущего кеша контекста, не знаю.
Код следует:
public class AmfResult : ActionResult
{
private readonly object _o;
private readonly string _response;
public AmfResult(string response, object o)
{
_response = response;
_o = o;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.ContentType = "application/x-amf";
var serializer = new AMFSerializer(context.HttpContext.Response.OutputStream);
var amfMessage = new AMFMessage();
var amfBody = new AMFBody();
amfBody.Target = _response + "/onResult";
amfBody.Content = _o;
amfBody.Response = "";
amfMessage.AddBody(amfBody);
serializer.WriteMessage(amfMessage);
}
}
Чтобы это работало, вам нужно декорировать метод на контроллере с помощьюAMFFilter
public class AMFFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.ContentType == "application/x-amf")
{
var stream = filterContext.HttpContext.Request.InputStream;
var deserializer = new AMFDeserializer(stream);
var message = deserializer.ReadAMFMessage();
var body = message.Bodies.First();
filterContext.ActionParameters["target"] = body.Target;
filterContext.ActionParameters["args"] = body.Content;
filterContext.ActionParameters["response"] = body.Response;
base.OnActionExecuting(filterContext);
}
}
}
, который будет выглядеть примерно так
[AMFFilter]
[HttpPost]
public ActionResult Index(string target, string response, object[] args)
{
// assume target == "TestMethod" and args[0] is a String
var message = Convert.ToString(args[0]);
return new AmfResult(response, "Echo " + message);
}
Код на стороне клиента для справки
//Connect the NetConnection object
var netConnection: NetConnection = new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
netConnection.connect("http://localhost:27165/Home/Index");
//Invoke a call
var responder : Responder = new Responder( handleRemoteCallResult, handleRemoteCallFault);
netConnection.call('TestMethod', responder, "Test");
private function onNetStatus(event:NetStatusEvent):void {
log(ObjectUtil.toString(event.info));
}
private function handleRemoteCallFault(...args):void {
log(ObjectUtil.toString(args));
}
private function handleRemoteCallResult(message:String):void {
log(message);
}
private static function log(s:String):void {
trace(s);
}
Если вы хотите вернуть ошибку, просто измените этострока в AMFResult
amfBody.Target = _response + "/onFault";
Мне нравится форматирование ObjectUtil.toString (), но просто удалите его, если у вас нет связанного с Flex.
BTWвам действительно нужно это в ASP.NET MVC?Может быть, достаточно простого обработчика ASHX и производительность будет лучше, я не знаю.Я предполагаю, что архитектура MVC - это плюс.