AMF的ActionResult的asp.net的MVC [英] AMF ActionResult for asp.net mvc

查看:229
本文介绍了AMF的ActionResult的asp.net的MVC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立一个MVC应用程序将通过AMF闪光灯沟通,
任何人知道,如果有任何的 AMF的ActionResult 在网站上提供?

修改

使用@mizi_sk答案(但不使用IExternalizable的),我这样做的ActionResult:

 公共类AmfResult:的ActionResult
{
    私人只读对象_O;    公共AmfResult(对象o)
    {
        _o = O;
    }    公共覆盖无效的ExecuteReuslt(ControllerContext上下文)
    {
        context.HttpContext.Response.ContentType =应用程序/ x-AMF;
        使用(VAR毫秒=新的MemoryStream())
        {
            //写对象
            VAR作家=新AMFWriter(毫秒);
            writer.WriteData(FluorineFx.ObjectEncoding.AMF3,_O);
            context.HttpContext.Response.BinaryWrite(ms.ToArray());
        }
    }
}

但就闪一边响应处理程序不被打到。

查尔斯在响应 - > AMF标签的我看到这个错误:


  

解析失败的数据(com.xk72.amf.AMFException:不支持AMF3数据包类型17 1)


这是原始的标签:

  HTTP / 1.1 200 OK
 服务器:ASP.NET开发服务器/ 10.0.0.0
 日期:星期一,2012 GMT 15点22分58秒5月14日
 的X ASPNET-版本:4.0.30319
 的X AspNetMvc-版本:3.0
 缓存控制:私人
 内容类型:应用程序/ x-AMF
 内容长度:52
 连接:关闭  3 / bingo.model.TestRequest param1coins名

和十六进制标签:

  00000000 11 0A 33 62 2F 6E 69 67 1207米2E 6D 6F 64 65 6C 2E 3 / bingo.model。
00000010 54 65 73 74 52 65 71 75 65 73 74 0D 70 61 72 61 TestRequest第
00000020 6D 31 0B 63 69 6F 6E 73 09 61 6E 65 6D 01 04 00 M1硬币名称
00000030 06 05 6A 1207米乔


解决方案

的技巧是使用 FluorineFx.IO.AMFMessage 与AMFBody结果对象,并设置一个内容属性。

您可以在查尔斯代理与其他工作示例看到这个(我用很大的的WebORB例子,具体的Flash Remoting基本调用AS3

我已经更新AMFFilter以支持AMFBody需要响应参数。也许这可以解决一些当前上下文缓存更优雅,不知道。

code如下:

 公共类AmfResult:的ActionResult
{
    私人只读对象_O;
    私人只读字符串_response;    公共AmfResult(字符串响应,对象o)
    {
        _response =响应;
        _o = O;
    }    公共覆盖无效的ExecuteReuslt(ControllerContext上下文)
    {
        context.HttpContext.Response.ContentType =应用程序/ x-AMF;        VAR串行=新AMFSerializer(context.HttpContext.Response.OutputStream);
        VAR amfMessage =新AMFMessage();
        VAR amfBody =新AMFBody();
        amfBody.Target = _response +/ onResult;
        amfBody.Content = _o;
        amfBody.Response =;
        amfMessage.AddBody(amfBody);
        serializer.WriteMessage(amfMessage);
    }
}

对于这个工作,你需要装饰的方法与AMFFilter控制器

 公共类AMFFilterAttribute:ActionFilterAttribute
{
    公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
    {
        如果(filterContext.HttpContext.Request.ContentType ==应用程序/ x-AMF)
        {
            VAR流= filterContext.HttpContext.Request.InputStream;            VAR解串器=新AMFDeserializer(流);
            VAR消息= deserializer.ReadAMFMessage();            变种体= message.Bodies.First();
            filterContext.ActionParameters [目标] = body.Target;
            filterContext.ActionParameters [ARGS] = body.Content;
            filterContext.ActionParameters [回应] = body.Response;            base.OnActionExecuting(filterContext);
        }
    }
}

这将是这个样子

  [AMFFilter]
[HttpPost]
公众的ActionResult指数(目标字符串,字符串响应,对象[]参数)
{
    //假设目标==TestMethod的和args [0]是String
    VAR消息= Convert.ToString(参数[0]);
    返回新AmfResult(响应,回声+消息);
}

客户端code,以供参考。

  //连接NetConnection对象
VAR的netconnection:=的NetConnection新的NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS,onNetStatus);
的NetConnection.connect(HTTP://本地主机:27165 /首页/索引);//调用方法
VAR响应:响应=新的Responder(handleRemoteCallResult,handleRemoteCallFault);
netConnection.call('TestMethod的,响应者,测试);私有函数onNetStatus(事件:NetStatusEvent):无效{
    日志(ObjectUtil.toString(event.info));
}私有函数handleRemoteCallFault(参数... args){无效
    日志(ObjectUtil.toString(参数));
}私有函数handleRemoteCallResult(消息:字符串):无效{
    日志(消息);
}私有静态功能日志(S:字符串):无效{
    跟踪(S);
}

如果您想返回的错,只是改变AMFResult这一行

  amfBody.Target = _response +/ onFault;

我喜欢ObjectUtil.toString()格式,而只是将其删除,如果你没有Flex的联系。

顺便说一句,你真的需要这在ASP.NET MVC?也许简单ASHX处理程序就足够了,性能会更好,我不知道。 MVC架构是一个加我presume。

I'm building a mvc application which will communicate with flash via AMF, anybody knows if there is any AMF ActionResult available on the web ?

EDIT:

using @mizi_sk answer (but without using IExternalizable) I did this ActionResult:

public class AmfResult : ActionResult
{
    private readonly object _o;

    public AmfResult(object o)
    {
        _o = o;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.ContentType = "application/x-amf";
        using (var ms = new MemoryStream())
        {
            // write object
            var writer = new AMFWriter(ms);
            writer.WriteData(FluorineFx.ObjectEncoding.AMF3, _o);
            context.HttpContext.Response.BinaryWrite(ms.ToArray());
        }
    }
}

but the response handler on the flash side doesn't get hit.

in Charles at the Response->Amf tab I see this error:

Failed to parse data (com.xk72.amf.AMFException: Unsupported AMF3 packet type 17 at 1)

this is the raw tab:

 HTTP/1.1 200 OK 
 Server: ASP.NET Development Server/10.0.0.0 
 Date: Mon, 14 May 2012 15:22:58 GMT 
 X-AspNet-Version: 4.0.30319
 X-AspNetMvc-Version: 3.0 
 Cache-Control: private 
 Content-Type:application/x-amf 
 Content-Length: 52 
 Connection: Close

  3/bingo.model.TestRequest param1coins name

and the Hex tab:

00000000  11 0a 33 2f 62 69 6e 67 6f 2e 6d 6f 64 65 6c 2e     3/bingo.model.
00000010  54 65 73 74 52 65 71 75 65 73 74 0d 70 61 72 61   TestRequest para
00000020  6d 31 0b 63 6f 69 6e 73 09 6e 61 6d 65 01 04 00   m1 coins name   
00000030  06 05 6a 6f                                         jo            

解决方案

The trick is to use FluorineFx.IO.AMFMessage with AMFBody as a result object and set a Content property.

You can see this in Charles proxy with other working examples (I've used great WebORB examples, specifically Flash remoting Basic Invocation AS3)

I've updated AMFFilter to support Response parameter that AMFBody needs. Maybe it could be solved more elegantly by some current context cache, don't know.

Code follows:

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);
    }
}

For this to work, you need to decorate method on the controller with 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);
        }
    }
}

which would look something like this

[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);
}

Client side code for reference

//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);
}

If you would like to return fault, just change this line in AMFResult

amfBody.Target = _response + "/onFault";

I like ObjectUtil.toString() formatting, but just remove it if you don't have Flex linked.

BTW, do you really need this in ASP.NET MVC? Maybe simple ASHX handler would suffice and performance would be better, I don't know. The MVC architecture is a plus I presume.

这篇关于AMF的ActionResult的asp.net的MVC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆