Silverlight错误传播和UserNamePasswordValidator

时间:2012-10-12 09:02:16

标签: wcf silverlight exception authentication

Scenario是一个使用Wcf服务的Silverlight客户端&自定义验证。为了缓解500/200状态代码问题(避免EndPointNotFound异常),我已经应用了SilverLightFaultBehaviour。但是,这不适用于UserNamePasswordValidator - 当从Validate()抛出FaultException时,它不会被SilverLightFaultMessageInspector的BeforeSendReply实现捕获。

到目前为止,我发现的唯一解决方法是使用备用客户端堆栈(WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);),但是使用它时会出现并发症,因为很多客户都不能忽略它们在虚拟机上,silverlight客户端不断崩溃(Silverlight 5 - Debugging npctrl.dll crashhttp://communities.vmware.com/thread/394306?tstart=0)。

我的主要动机是我希望能够区分失败的登录和连接错误(以下代码来自客户端异步回调方法,并且仅适用于客户端堆栈):

if (e.Error is MessageSecurityException)
{
    this.HasLoginFailed.Value = Captions.Login_FailedLogin;
}
else
{
    this.HasLoginFailed.Value = Captions.Login_FailedConnection;
}

在从UserNamePasswordValidator抛出FaultException时,是否还有其他方法可以修改发送的消息?或者任何在概念上不同的方式进行自定义身份验证而不是我正在使用的方式,这使我能够修改消息状态或保持200,或者只是为了能够区分连接失败和不良凭据?

我的usernamepassword reg的服务器端代码:

var serviceCredential = host.Description.Behaviors.Find<ServiceCredentials>();
serviceCredential.UserNameAuthentication.UserNamePasswordValidationMode =
                    UserNamePasswordValidationMode.Custom; 
serviceCredential.UserNameAuthentication.CustomUserNamePasswordValidator =
                    new MyValidator();

1 个答案:

答案 0 :(得分:0)

当您从FaultException中抛出MyValidator时,它会被InnerException包裹起来MessageSecurityException,这可能就是您没有注意到的原因能够以FaultException直接捕获它。

要为您要投掷的错误添加一些信息,您可以做的是添加FaultCode

throw new FaultException(
    "Invalid user name or bad password.",
     new FaultCode("BadUserNameOrPassword")
);

然后,捕获客户端的异常并检索您的FaultCode

try { ... }
catch (MessageSecurityException e)
{
    FaultException fault = (FaultException) e.InnerException;
    String faultCode = fault.Code.Name;
    // you can now display a meaningful error with the faultCode
}

我希望它会有所帮助!