如果不自己编写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
写入写入 aStringWriter
并ToString()
对其执行操作,您将拥有序列化实体,您可以在将其写入输出流之前记录并执行任何您想做的事情。
虽然上述所有示例代码都基于 XML 序列化和反序列化,但无论您的应用程序使用何种格式,都应适用相同的原则。