0

我编写了一个ExceptionInterceptor将操作调用包装在try/catch中以进行集中异常处理的方法。我还想做的是集中处理 HTTP 状态代码,但我似乎无法从我的IOperationInterceptor. 我的 Interceptor 将ICommunicationContext其作为依赖项并将其设置OperationResult为 eg OperationResult.BadRequest,但 OpenRasta 仍将以下内容写入日志:

Step 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.

我也尝试过IResponse.StatusCode明确设置,但没有效果。似乎因为我想要响应的 ResponseResource 是注册的有效资源ResourceSpace(尽管没有 URI),所以状态代码被忽略,并且常规渲染管道向前推进认为“这看起来不错”。

为什么 OpenRasta 会忽略我的 StatusCode?

4

1 回答 1

1

经过更多挖掘后,我发现您不能直接从IOperationInterceptor. 相反,您需要在集合中存储您需要的任何数据,这些数据在您的实现ICommunicationContext.PipelineData中是有意义的。IOperationInterceptor例如,我有以下BeforeExecute实现:

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

    return true;
}

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

当您在内部存储了所有想要的数据后,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 方法变薄并专注于它们正在解决的问题。处理程序方法现在可以抛出常规异常,而不是返回OperationResult左右,我的IOperationInterceptor实现将捕获这些异常,然后我的实现可以用适当的响应IPipelineContributor覆盖。OperationResult

于 2011-07-15T13:10:34.817 回答