在 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 中是否有一个扩展点可以让我在这两种方法之间抛出此错误?
好的,错误的方法。我所要做的就是在 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;
}
这实现了我的目的。
希望这对某人有所帮助。)