Следуя инструкциям здесь
http://beyondrelational.com/modules/2/blogs/79/posts/11543/throwing-exceptions-from-wcf-service-faultexception.aspx
Я получил следующий код:
Интерфейс:
[ServiceContract]
public interface IAuthenticator
{
[OperationContract]
[FaultContract(typeof(AuthenticationException))]
Account authenticateApplication(string userName, string Password);
}
Исключение:
[DataContract]
public class AuthenticationException
{
private string validationError;
[DataMember]
public string ValidationError
{
set { validationError = value; }
get { return validationError; }
}
public AuthenticationException(string valError)
{
validationError = valError;
}
}
И, наконец, вот как я выкидываю ошибки в моей реализации authenticateApplication:
catch (InvalidUsernameException)
{
throw new FaultException<AuthenticationException>(new AuthenticationException("The username you entered could not be found in our database."), new FaultReason("Error"));
}
Проблема в том, что вместо отправки ошибки клиенту приложение WCF приложения завершает работу, говоря, что я не обработал исключение.
Если это имеет значение, вот как я звоню своему клиенту:
try
{
myAcc = httpProxy.authenticateApplication("some text", "some other text");
}
catch (FaultException<AuthenticationException> ex)
{
MessageBox.Show(ex.Detail.ValidationError);
return;
}
Редактировать: Вот мой след стека:
at AuthenticatorService.Authenticator.authenticateApplication(String userName, String Password) in E:\Miscellaneous\Applications\Web 2.0 Creator\AuthenticatorService\AuthenticatorService\AuthenticatorService\Authenticator.cs:line 109
at SyncInvokeauthenticateApplication(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
Редактировать Редактировать:
Вот полный блок try try:
try
{
using (myConnection)
{
using (myCommand)
{
//Tell it to execute the stored procedure on the database
myCommand.CommandText = "findUsername";
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.Add("@userName", SqlDbType.NVarChar, 20);
myCommand.Parameters["@userName"].Value = userName;
//If the reader returns 0 rows, that means the username doesn't exist in the database, so step there and return an exception
using (myReader)
{
myReader = myCommand.ExecuteReader();
if (myReader.HasRows == false)
{
InvalidUsernameException iue = new InvalidUsernameException();
throw iue;
}
else //Else we store the fields
{
myAcc.Password = myReader[1].ToString();
isActive = Convert.ToBoolean(myReader[2]);
myAcc.Key = myReader[3].ToString();
myAcc.ExpiryDate = myReader[4].ToString();
}
}
}
}
}
catch (SqlException)
{
throw new FaultException<AuthenticationException>(new AuthenticationException("There was an error while connecting the database, please contact support."), new FaultReason("Error"));
}
catch (InvalidOperationException)
{
throw new FaultException<AuthenticationException>(new AuthenticationException("An error in the program while connecting to the database."), new FaultReason("Error"));
}
catch (InvalidUsernameException)
{
throw new FaultException<AuthenticationException>(new AuthenticationException("The username you entered could not be found in our database."), new FaultReason("Error"));
}
catch (Exception)
{
throw new FaultException<AuthenticationException>(new AuthenticationException("There was a general error during the process."), new FaultReason("Error"));
}