I have wcf service and I used it into ASP.net MVC and WCF RIA service. I am able to catch fault exception into ASP.net MVC but not able to catch into WCF RIA Service.
Following code is for wcf ria service where I use WCF Service
public class MyService : LinqToEntitiesDomainService<MyEntities>
{
try
{
ExternalServiceProxy.SaveData();
}
catch(FaultException<ExceptionInfo> ex)
{
//Not able to catch faultexception
}
catch(Exception ex)
{
//Every time catch exception and faultexception information lost
}
}
Are you sure that you have the correct type of exception? In your "catch(Exception ex)" statement, check the specific type of the exception. It's probably a subclass of Exception, but not a FaultException.
Related
I have a WCF service with wsHttpBinding. Everything works just fine, but I have got problem with catching faults on my client, sent from my custom Authenticator.
I use custom Authenticator code from msdn:
https://msdn.microsoft.com/en-us/library/aa702565(v=vs.110).aspx
// This throws an informative fault to the client.
throw new FaultException("Unknown Username or Incorrect Password");
this comment says that we are throwing an informative fault to the client, but i can't catch it on the client side:
bool isReachable = false;
try {
isReachable = client.agentIsReachable();
}
catch(FaultException faultException){
MessageBox.Show(faultException.Message);
}
While debugging I can see, that a fault is thrown, but my clients catch code does not work. My communication channel faults, but without fault exception. Then i catch a .NET ex, saying that I am trying to use faulted proxy.
Everything works great when i throw faults from any of my service methods. I can catch them on my client.
Is it really possible to catch faults, sent from Authenticator. And what is the best way to pass an informative message to the client when authentication fails?
Client-side, the exception you have to catch is not a FaultException but a MessageSecurityException (using System.ServiceModel.Security).
Then you can retrieve your FaultException with the InnerException attribute of the MessagSecurityException you caught. In your case, you'll end up with something similar to this:
catch (MessageSecurityException e)
{
FaultException fault = (FaultException) e.InnerException;
MessageBox.Show(faultException.Message);
}
I hope it will help.
I need to handle the exception in WCF Service application.
But in the windows application I can't get the error message. It's only display as Bad Request.
In the WCF Service throw the following exception.
throw new WebFaultException<string>(string.Format("Invalid Client ID.", clientID), HttpStatusCode.BadRequest);
In your windows application (client), you have to catch the exception and get the detail of the error
try
{
client.YourServiceMethod();
}
catch (FaultException<string> ex)
{
MessageFault messageFault = ex.CreateMessageFault();
Console.WriteLine(messageFault.GetDetail<string>());
}
I have made a Silverlight Application WCF RIA Services which have's a login page that verify the username and password in a database ... it has worked perfectly when I debug from VS2010 but when I publish to IIS7 it doesn't connect with database any more ... I've made all the settings in the Web.config ... I've added the clientaccesspolicy.xml and crossdomain.xml to my project ... added the MIME types to IIS7 with no result ... I find an error with development tools from IE9 and it says :
SCRIPT5022: Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details. at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at MaG.ServiceReference1.LoginCompletedEventArgs.get_Result()
at MaG.MainPage.connection_LoginCompleted(Object sender, LoginCompletedEventArgs e)
at MaG.ServiceReference1.Service1Client.OnLoginCompleted(Object state)
MaGTestPage.html, line 1 character 1
I appeal the Login method client to webservice like this:
try
{
ServiceReference1.Service1Client connection = new ServiceReference1.Service1Client();
connection.LoginCompleted += new EventHandler<ServiceReference1.LoginCompletedEventArgs>(connection_LoginCompleted);
connection.LoginAsync(textBox1.Text, passwordBox1.Password);
}
catch (Exception ex)
{
Console.Write(ex.InnerException);
}
The reason for this will be found in your event handler, connection_LoginCompleted. Use this approach to check, first, for any service error:
void connection_LoginCompleted(object sender, LoginCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.ToString());
}
else
{
// handle result
}
}
If you try to access e.Result when there is an error, the object will throw the exception you see.
I have a WCF service that's hosted in IIS, and uses a WS HTTP binding (the external service). This service ends up calling a second WCF service that's hosted in a Windows service, over Net TCP (the internal service). When the internal service throws a FaultException, the external service crashes rather than throwing it to the client. All the client sees is the connection being forcibly closed.
The internal service uses the Enterprise Library Validation Application Block to validate the incoming messages. When validation errors occur, the service throws a FaultException<ValidationFault>.
Both the internal and external service have a [FaultContract(typeof(ValidationFault)] attribute in the service contract. If I change the external service to just immediately throw a new FaultException<ValidaitonFault>, this gets back to the client fine. I can catch the exception from the internal service in the external service, but if I try to re-throw it, or even wrap it in a new exception and throw that, the whole Application Pool in IIS crashses. I can't see anything useful in the event log, so I'm not sure exactly what the problem is.
The client object the external service uses to communicate with the internal service is definitely being closed and disposed of correctly. How can I get the internal service's faults to propagate out to the client?
updated:
Below is a simplified version of the external service code. I can catch the validation fault from the internal service call. If I throw a brand new FaultException<ValidationFault>, everything is fine. If I use the caught exception, the connection to the external client is broken. The only difference I can see is when debugging the service - trying to use the caught exception results in a message box appearing when exiting the method, which says
An unhandled exception of type
'System.ServiceModel.FaultException`1'
occurred in mscorlib.dll
This doesn't appear if I throw a brand new exception. Maybe the answer is to manually copy the details of the validation fault into a new object, but this seems crazy.
public class ExternalService : IExternalService
{
public ExternalResponse DoSomething(ExternalRequest)
{
try
{
var response = new ExternalResponse();
using (var internalClient = new InternalClient())
{
response.Data = internalClient.DoSomething().Data;
}
return response;
}
catch (FaultException<ValidationFault> fEx)
{
// throw fEx; <- crashes
// throw new FaultException<ValidationFault>(
// fEx.Detail as ValidationFault); <- crashses
throw new FaultException<ValidationFault>(
new ValidationFault(new List<ValidationDetail> {
new ValidationDetail("message", "key", "tag") }),
"fault message", new FaultCode("faultCode"))); // works fine!
}
}
}
I have almost the exact design as you and hit a similar issue (not sure about a crash, though!).
If I remember correctly, even though the ValidationFault is a common class when the Fault travels over the wire the type is specific to the WCF interface. I think this is because of the namespace qualifiers on the web services (but this was a while back so I could be mistaken).
It's not terribly elegant, but what I did was to manually re-throw the exceptions:
try
{
DoStuff();
}
catch (FaultException<ValidationFault> fe)
{
HandleFault(fe);
throw;
}
...
private void HandleFault(FaultException<ValidationFault> fe)
{
throw new FaultException<ValidationFault>(fe.Detail as ValidationFault);
}
Well, it works if I do this, but there must be a better way...
This only seems to be a problem for FaultException<ValidationFault>. I can re-throw FaultException and FaultException<SomethingElse> objects with no problems.
try
{
DoStuff();
}
catch (FaultException<ValidationFault> fe)
{
throw this.HandleFault(fe);
}
...
private FaultException<ValidationFault> HandleFault(
FaultException<ValidationFault> fex)
{
var validationDetails = new List<ValidationDetail>();
foreach (ValidationDetail detail in fex.Detail.Details)
{
validationDetails.Add(detail);
}
return new FaultException<ValidationFault>(
new ValidationFault(validationDetails));
}
I would like to throw custom exception like some error message as an exception from WCF web service and trying receiver this exception error message in client app on calling web service method.
how to throw custom exception from WCF web Service and receive same exception error at client side.
WCF Web Service Method:
public bool Read()
{
if (IsUserValid() == false)
{
throw new Exception("Authorized user");
}
}
At Client Side
try
{
_client.Read();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
Result: Always throw error message as an exception **i.e.
"System.ServiceModel.FaultException:
The server was unable to process the
request due to an internal error. For
more information about the error,
either turn on
IncludeExceptionDetailInFaults (either
from ServiceBehaviorAttribute or from
the configuration
behavior) on the server in order to
send the exception information back to
the client, or turn on tracing as per
the Microsoft .NET Framework 3.0 SDK
documentation and inspect the server
trace logs."
This is code is throwing exception but not returning same error message as thrown from WCF web service as an exception error
Please suggest
In WCF, you should not throw standard .NET exceptions - this is contrary to the potentially interoperable nature of WCF - after all, your client could be a Java or PHP client which has no concept of .NET exceptions.
Instead, you need to throw FaultExceptions (which is the standard behavior for WCF).
If you want to convey back more information about what went wrong, look at the generic FaultException<T> types:
SERVER:
public bool Read()
{
if (IsUserValid() == false)
{
throw new FaultException<InvalidUserFault>("User invalid");
}
}
Or alternatively (as suggested by #MortenNorgaard):
public bool Read()
{
if (!IsUserValid())
{
InvalidUserFault fault = new InvalidUserFault();
FaultReason faultReason = new FaultReason("Invalid user");
throw new FaultException<InvalidUserFault>(fault, faultReason);
}
}
CLIENT:
try
{
_client.Read();
}
catch (FaultException<InvalidUserFault> e)
{
MessageBox.Show(e.Message);
return;
}
You should declare your InvalidUserFault as WCF data contracts and define what members might travel back with that type (i.e. error code, error message etc.).
[DataContract]
[Serializable()]
public class BusinessFault
{
... add your fault members here
}
And you should then decorate your service methods with the possible faults it can throw:
[FaultContract(typeof(InvalidUserFault)]
[OperationContract]
public bool Read()
.....
Of course, the "quick'n'dirty" hack is to simply define that the server returns exception details in its FaultExceptions:
<serviceBehaviors>
<behavior name="EmployeeManager_Behavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
and then you can inspect the FaultException's .Detail for the actual exception that happened on the server - but again: this is more of a development-time only hack rather than a real solution.
Marc
To get this to work you need to do two things:
Define the fault contract in the interface (WCF contract)
Throw the exception as a fault exception