1

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

有谁知道我该怎么做?

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

4

1 回答 1

1

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

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写入写入 aStringWriterToString()对其执行操作,您将拥有序列化实体,您可以在将其写入输出流之前记录并执行任何您想做的事情。

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

于 2012-04-19T15:24:38.193 回答