从OpenRasta中的IOperationInterceptor设置HTTP状态代码

时间:2011-07-13 12:15:11

标签: http http-status-codes openrasta

我编写了一个ExceptionInterceptor,它将操作调用包装在try / catch中,以便进行集中式异常处理。我还想做的是集中式HTTP状态代码处理,但我似乎无法在IOperationInterceptor内设置HTTP状态代码。我的拦截器将ICommunicationContext作为依赖项并将其OperationResult设置为例如OperationResult.BadRequestStep into: Stepping over non-user code 'OpenRasta.Pipeline.PipelineRunner.RunCallGraph' 38-[2011-07-08 09:11:37Z] Start(1) Entering PipelineRunner: Executing contributor OperationResultInvokerContributor.RunOperationResult 38-[2011-07-08 09:11:37Z] Information(0) Executing OperationResult OperationResult: type=OK, statusCode=200. ,但OpenRasta仍将以下内容写入日志:

IResponse.StatusCode

我也尝试过明确地设置ResourceSpace,但它没有效果。似乎因为我要响应的ResponseResource是在{{1}}中注册的有效资源(虽然没有URI),但状态代码被忽略,常规渲染管道向前推进,认为“这看起来还不错”。

为什么OpenRasta会忽略我的StatusCode?

1 个答案:

答案 0 :(得分:1)

经过一番挖掘后,我发现你无法直接从IOperationInterceptor覆盖HTTP状态代码。相反,您需要在ICommunicationContext.PipelineData实施中的任何有意义的地方存储IOperationInterceptor集合中所需的任何数据。例如,我有以下BeforeExecute实现:

public bool BeforeExecute(IOperation operation)
{
    if (operation.Inputs.Count() > 0)
        this.inputMember = operation.Inputs.First();

    return true;
}

BeforeExecute中设置inputMember允许我通过this.inputMember.Binder.BuildObject().Instance检索实体(通过HTTP POST或PUT接收),并在OutputMember中产生新的RewriteOperation方法

当您在ICommunicationContext.PipelineData中存储了所需的所有数据后,您可以继续处理存储的数据并在IPipelineContributor实现中做出相应的响应。您可以通过订阅After<KnownStages.IOperationExecution>()事件来执行此操作:

public void Initialize(IPipeline pipelineRunner)
{
    pipelineRunner
        .Notify(RenderOnException)
        .After<KnownStages.IOperationExecution>();
}

RenderOnException方法如下所示:

private static PipelineContinuation RenderOnException(ICommunicationContext context)
{
    if (!context.PipelineData.ContainsKey(ExceptionInterceptor.Key))
        return PipelineContinuation.Continue;

    var interestingDataStoredByTheOperationInterceptorImplementation =
        context.PipelineData["SomeKey"];

    // Set context.OperationResult to something meaningful.

    // Instruct the pipeline to render now
    return PipelineContinuation.RenderNow;
}

虽然这可能不是实现这一点的最佳方式,但它可以工作并最终使各个Handler方法变得更薄,并专注于他们正在解决的问题。 Handler方法现在可以抛出我的OperationResult实现将捕获的常规异常,而不是向左和向右返回IOperationInterceptor,然后我的IPipelineContributor实现可以使用适当的方式覆盖OperationResult响应。