2012-04-19 35 views
1

我需要访问OpenRasta中的编码流,然后将其发送到客户端。我尝试过使用PipelineContributor并在KnownStages.IEnd之前注册它,在KnownStages.IOperationExecution之后和KnownStages.AfterResponseConding之后尝试,但在所有情况下context.Response.Entity流为null或为空。访问OpenRasta中的编码流

任何人都知道我该怎么做?

另外,我想在相当早的时候找出所需的编解码器,但是当我在KnowStages.ICodecRequestSelection之后注册时,它返回null。我只是觉得我错过了这些管道贡献者的一些想法。

回答

1

没有写你自己的Codec(顺便说一句,这很容易),我不知道如何获得实际的字节流发送到浏览器。我这样做的方式是在IResponseCoding已知阶段之前序列化ICommunicationContext.Response.Entity。伪代码:

class ResponseLogger : IPipelineContributor 
{ 
    public void Initialize(IPipeline pipelineRunner) 
    {    
     pipelineRunner 
      .Notify(LogResponse) 
      .Before<KnownStages.IResponseCoding>(); 
    } 

    PipelineContinuation LogResponse(ICommunicationContext context) 
    { 
     string content = Serialize(context.Response.Entity); 

    } 

    string Serialize(IHttpEntity entity) 
    { 
     if ((entity == null) || (entity.Instance == null)) 
      return String.Empty; 

     try 
     { 
      using (var writer = new StringWriter()) 
      { 
       using (var xmlWriter = XmlWriter.Create(writer)) 
       { 
        Type entityType = entity.Instance.GetType(); 
        XmlSerializer serializer = new XmlSerializer(entityType); 
        serializer.Serialize(xmlWriter, entity.Instance); 
       } 

       return writer.ToString(); 
      } 
     } 
     catch (Exception exception) 
     { 
      return exception.ToString(); 
     } 
    } 
} 

ResponseLogger注册的常用方法:

ResourceSpace.Uses.PipelineContributor<ResponseLogger>(); 

如前所述,这并不一定给你发送到浏览器的确切字节流,但它是足够接近因为我的需要,因为发送到浏览器的字节流基本上是相同的序列化实体。

通过编写自己的编解码器,您可以用不超过100行的代码点击IMediaTypeWriter.WriteTo()方法,我猜想这是您的字节传输到云端之前的最后一道防线。在这,你基本上只是做一些简单的像这样:

public void WriteTo(object entity, IHttpEntity response, string[] parameters) 
{ 
    using (var writer = XmlWriter.Create(response.Stream)) 
    { 
     XmlSerializer serializer = new XmlSerializer(entity.GetType()); 
     serializer.Serialize(writer, entity); 
    } 
} 

如果你的,而不是直接写入到IHttpEntity.Stream写入StringWriter,并在其上做ToString(),你就会有系列化的实体,您可以登录并在写入输出流之前做任何你想做的事情。

虽然上述所有示例代码均基于XML序列化和反序列化,但无论应用程序使用何种格式,都应遵循相同的原则。

+0

是否有可能链接编解码器?我需要在内容被任何编解码器合适编码之后获取内容。 rss或atom – PlanetWilson 2012-04-20 09:00:45

+0

不幸的是我的实体不是可序列化的,可能做太多的工作让它们如此。思考我可能不得不使用一个单独的HTTP模块:(讨厌,但会工作 – PlanetWilson 2012-04-20 09:06:38

+1

创建一个新的编解码器,注册它为您的媒体类型,并从那里调用现有的编解码器,拦截http流很容易。 – SerialSeb 2012-05-31 21:36:51