我编写了一个ExceptionInterceptor
,它将操作调用包装在try
/ catch
中,以便进行集中式异常处理。我还想做的是集中式HTTP状态代码处理,但我似乎无法在IOperationInterceptor
内设置HTTP状态代码。我的拦截器将ICommunicationContext
作为依赖项并将其OperationResult
设置为例如OperationResult.BadRequest
。 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.
,但OpenRasta仍将以下内容写入日志:
IResponse.StatusCode
我也尝试过明确地设置ResourceSpace
,但它没有效果。似乎因为我要响应的ResponseResource是在{{1}}中注册的有效资源(虽然没有URI),但状态代码被忽略,常规渲染管道向前推进,认为“这看起来还不错”。
为什么OpenRasta会忽略我的StatusCode? p>
答案 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
响应。