在 IDispatchOperationSelector.SelectOperating 和 ServiceAuthen

本文关键字:ServiceAuthen SelectOperating IDispatchOperationSelector | 更新日期: 2023-09-27 18:36:51

我正在编写一个需要处理定制旧消息格式 (xml) 的 wcf 服务。当我第一次解析传入的xml时,它是在IDispatchOperationSelector中的SelectOperation方法中。

我要做的第一件事是针对 xsd 验证 xml,以确保传入消息的格式正确。如果它未能通过此验证,我将抛出一个 XmlSchemaValidationException 并在 IErrorHandler 实现中捕获它,目的是向客户端返回 400 - 错误请求错误。

不幸的是,在IErrorHandler的ProvideFault方法中,OperationContext.Current 为空。我认为这是因为 OperationSelector 是 OperationContext.Current 创建的一部分,或者在 OperationContext.Current 创建之前被调用。因此,我没有在操作选择器中抛出错误,而是决定在操作选择器中返回字符串"error"并设置消息。Headers.Action 也"错误",并将所需的异常添加到消息属性中,然后在创建操作上下文后抛出它。

问题是我的代码中要命中的下一个扩展点是ServiceAuthenticationManager.Authenticate方法。如果我检查消息。Headers.Action 并找到错误,然后在此方法中抛出该错误,它被框架吞噬,并且传递给我的错误处理程序的错误是"用户未经过身份验证",我认为这是有道理的。

所以我想我的问题是,WCF 中是否有一个扩展点可以让我在这两种方法之间抛出此错误?

在 IDispatchOperationSelector.SelectOperating 和 ServiceAuthen

好的,错误的方法。我所要做的就是在 OperationSelector 中抛出错误,然后在 ErrorHandler ProvideFault 方法中抛出错误,ref Message fault 为 null,所以我使用了以下代码。

if (error is XmlSchemaValidationException && fault == null)
{
   fault = Message.CreateMessage(version, new FaultException().CreateMessageFault() , "error");
    fault.Properties[HttpResponseMessageProperty.Name] = new HttpResponseMessageProperty
    {
        StatusCode = HttpStatusCode.BadRequest,
        SuppressEntityBody = true
    };
    return;
}

这实现了我的目的。

希望这对某人有所帮助。)