Skip to main content
Home Forums Silverlight Programming Programming with .NET - General WCF Services with faultexception
24 replies. Latest Post by minus34 on July 15, 2009.
(1)
eric_del...
Member
181 points
43 Posts
06-11-2008 11:02 AM |
"Receiving SOAP faults is not supported due to Web browser limitations"
I'm scared, really
Mi autogenerated service proxy has my typed exception object, In the response soap message i see mi exception perfectly, but the silverlight application throw error 404 I suppose by "Receiving SOAP faults is not supported due to Web browser limitations"
chandler...
269 points
81 Posts
06-11-2008 11:48 AM |
I have noticed this behaviour as well and when I posted about it before all I heard were crickets. What I wound up doing was catching the error in the proper method for the Reference.cs file that is generated in the proxy. Definitely not optimal because if you ever update your service reference it will over write your code.
sladapter
All-Star
17179 points
3,132 Posts
06-11-2008 12:33 PM |
At least in beta 1, Fault Exception is not supported in Silverlight. I don't think beta2 changed that but I could be wrong.
Here is the way I do it:
I created a custom exception in my WCF side. I have one generic WCF function for my all WCF calls. The return type is called ResponseData I defined this way:
[DataContract] public class ResponseData { [DataMember] public string StringResult { get; set; } [DataMember] public int IntResult { get; set; } [DataMember] public double NumericResult { get; set; } [DataMember] public bool BooleanResult { get; set; } [DataMember] public CustomException Error { get; set; } [DataMember] public DataSetData DataSetResult { get; set; } [DataMember] public Dictionary<string, string> DictionaryResult { get; set; } }
[DataContract] public class CustomException { [DataMember(Order = 0)] public string Message { get; set; } [DataMember(Order = 1)] public CustomException InnerException; public Exception ToException() { Exception e; CustomException ce = this; if (ce.InnerException != null) { Exception inner = ce.InnerException.ToException(); e = new Exception(ce.Message, inner); } else e = new Exception(ce.Message); return e; } }
So if my WCF function I catch any exception and pass that exception to MyResponseData.Error;
[OperationContract] public ResponseData ProcessRequest(RequestData request) { return Process(request); }
private ResponseData Process(RequestData request)
{
ResponseData result = new ResponseData(); try
{ ...
result.StringResult = "Something"; // }
catch (Exception ex) { while (ex.InnerException != null) ex = ex.InnerException; result.Error = new CustomException(); result.Error.Message = ex.Message + ex.StackTrace; } return result; // this result could contains Error or could contain real data.
}
On Silverlight side in MyWebServiveCompleted call I check both e.Error and e.Result.Error
Hope this would help if somebody want to do this way. Use this CustomExeption I can also send my Exception in the Silverlight side back to Server to do Exception logging.
vitya
111 points
75 Posts
06-14-2008 11:28 AM |
sladapter: Here is the way I do it: I created a custom exception in my WCF side. I have one generic WCF function for my all WCF calls. The return type is called ResponseData I defined this way:
Hi sladapter,
I like this approach very much, thanks for sharing it!
jordanha...
190 points
104 Posts
08-07-2008 6:22 AM |
Hi sladaper, I thought of creating an exception model such as this, but now that Beta 2 is out I see they have added support for FaultException.
However in my WCF method, if I try to throw a new FaultException from the catch(Exception) the runtime stops with error "FaultException was unhandled by user code.
Have you had a chance to play with FaultException in Beta 2 ??
thanks.
doolittle
74 points
26 Posts
08-07-2008 7:45 AM |
Have to dissapoint you there Jordan. They did change something concerning the FaultExceptions.In Beta 1, adding service reference to WCF service with FaultContracts specified caused compilation errors (as you probably now).Because this information was added to the Reference class, but Silverlight doesn't know what to do with this.In Beta 2 they changed it so this information is no longer added to the reference class.Hence no more compilation errors, but it still doesn't work.Two weeks ago I sent a mail to Tim Heuer about this (and other WCF/Silverlight stuff, you can only try to get an answer right :-)) and this was his answer:
08-07-2008 8:02 AM |
Great, thanks for the detailed response. I do like sladapter's idea of a single generic operation contract (since it would reduce the download size on the client), though i don't see how I could do this to support the many different data contracts I need. These are being used in the client side app as well to simplify things and avoid code duplication.
I will look into your idea of using an out param for the exception.
ps. anyone know when we can expect RC1?
08-07-2008 8:19 AM |
No problem. I started of with the exception being part the response but got stuck :-).The reason I got stuck was because of our current WCF-service architecture (which in all modesty is pretty good ;)).Reason I got stuck was that we (as you have I guess) have many OperationContracts each returning a specific typed response.These responses all inherit from a base class. And it's in this base class I added the exception object.But the problem was I wanted to handle exceptions in one place (which our architecture provides). But currently I couldn't get to the type the response should be in that place.Maybe this is a bit of an abstract description. But it's just to say that it was indeed my intention to add it to the response.But didn't want to change to many things to the current architecture of the WCF service as this 'exception work around' is hopefully only temporary...
Of course I had to ask Mr Heuer about the future of SL aswell. Here is what he answered to that (I basically asked when final SL2 will be available and what is on their future roadmap, again I can only ask :)):
08-07-2008 8:37 AM |
Surprises me too, as I've been in meetings with MS regarding silverlight, and every indication was a Fall release. I would assume this to be PDC. I can't think of a better time or place to release the final of Silverlight 2, if it is as important to them as they make it to be. I also spoke of roadmap with some people on the SL team, who stated that there's already plans up to version 5.
But i agree with Mr Heuer, no point getting ahead of themselves, just get the final v2 out and see where things stand. This workaround is fine for a while (out param works nicely btw), I would rather they fix things like localization which is im complete shambles right now.
My other big concern, which no one seems to be addressing, is how MS is planning on getting the runtime propogated. Believe me, NBC's olympic coverage won't be it. They should've bought youtube before google did... No corporate networks will install it until the final release has come out.
08-07-2008 10:11 AM |
doolittle,
Thank you for all the information.
So currently we still need this workaround for passing WCF exception back to Silverlight. I agree that if you have a lot of DataContracts, using out parameter in all Service functions should be the best choice.
For me, I only need to pass generic "DataSetData" back and forth so I can use the generic method. I only have a few very generic OperationContracts and DataContracts even our application contains more than 1000 tables.
08-07-2008 11:38 AM |
sladapter, it would be nice to have such simple data requirements.
Do you not need to bring back combined information? such as details of a client with lists of things they're allowed to do?
08-07-2008 12:05 PM |
Yes, actually I bring back meta data and real data. The meta data is for describing each field of an object such as field data type, if it's required, if it's editable, the Max field length, security right and access right check id, data format, display control type and edit control type etc. With all those information we basically can automate control building process.
Most security check are done in the Business tier so the data I bring back is for the current user only. If the user does not have certain right for certain field, the data returned won't even contains that information.
Our data requirements is not simple at all, it need to be very dynamic. Each user can select different columns (within their right) to show their data. They can change this selection dynamically. Because the nature of our data requirement is so dynamic, generic way (using DataSet rather than define each DataObject) is a better way for us. It requires a lot of thinking before hand and it's not that straight forward either. But once the structure is there, adding more objects and pages are simple and easy.
08-07-2008 2:20 PM |
Looks like you are already doing what we ultimatly would like to be doing :).At least the part where you send the info with information on what the client is actually allowed to do with it.
You might have noticed my thread http://silverlight.net/forums/t/22022.aspx.I'm really interested if for your, pretty big it seems, project you used any existing framework.If not what kind of structure are you using.I'm not asking for any code, but is it based on some guidelines?Did you find those somewhere??Would be very interested in that...
Aaro
6 points
3 Posts
08-30-2008 11:08 PM |
A Silverlight business app would need it's state managed on the server. And it's probably no coincidence that the state machine workflow service seems like it could be ideal for this. This could be a lot more elegant than the old ASP.Net session state. However the current ReceiveActivity seems to be designed for SOAP features. So when a method is called of the wrong state all I get back is the 404 errors. Does anyone know of a work around for this? And this seems pretty obvious way to make Silverlight apps so one of the gurus in the blogsphere must be working on a decent demo...? (that Calculator sample is pretty lame).
I can return errors within my functions using a property in a DataContract but I don't know how to override the workflow services when it throws a fault exception. I'm in process of learning how to use it so there are big gaps in my knowledge of it.
08-31-2008 10:55 AM |
If you do no catch the Exception thrown in your Service code, you will get 404 error. But if you catch the final exception before your Service code return, wrap that error in ResultData back or you can use Out Parameter to return the error, you should get a meaningful error instead of 404 error.
09-01-2008 4:29 AM |
agreed. I use the out parameter method as it's easier than adding a property if you have a lot of DataContracts. Also hoping the FaultException is fixed in the next release so can easily strip out the out param.
littlesteps
9 Posts
09-08-2008 5:01 AM |
Instead of "out params" approach, I prefer to manage "Status".
Status management is a specific service dedicated to error handling with "strong-typed" errors (like non-generic FaultException).
Typically, when a method from a service returns "false", the client has to call a service like "GetLastStatus" that enables him to retrieve error details from the last call.
I design several DataContracts for different kind of Status. Basically: KernelErrorStatus, BusinessErrorStatus, and so on.
Of course this kind of approach depends on service implementation (single / per call / per session mode and multi-threading or not), and has to be designed correctly to fit well.
But I think it helps to get nice architecture for error handling and prevents developpers to "pollute" or "complicate" method signatures in the service contracts.
Hope this helps,
sravoux
4 points
2 Posts
09-22-2008 4:07 AM |
In order to keep the same signatures on my WCF services, I've done something like what you said (with a GetLastError() Method) :
http://silverlight.net/forums/p/19875/94861.aspx#94861
Thanks
surielb
8 points
5 Posts
01-23-2009 5:23 AM |
I have put together an article on Code project explaining in detail a re-usable set of classes to allow Service Exception handling in Silverlight.
The code wrapps itself around the service calls and adds extra info to the response message if an exception is handled.
This solution works for all scenarios including methods that return primitives or void, and keeps the compatibility with the standard WCF Fault handling.
The article can be found at Catch and Handle WCF Service Exceptions in Silverlight
01-28-2009 2:01 PM |
surielb,
Thanks for the article.
Here is another similar solution from Microsoft Web Service team which basically has the same concept, but the code they provided is even more straightforward and simpler without having to change much of the current code. All you need to do to create BasicHttpMessageInspectorBinding instead of BasicHttpBinding and pass it to the Service constructor. Then the e.Error should return you all the exceptions thrown from the Service end.
See discussion in this blog: http://blogs.msdn.com/silverlightws/
You can download the Silverlight Fault Handle sample code from here:
http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=silverlightws&DownloadId=3473
baskarangr
2 points
1 Posts
03-18-2009 7:19 AM |
Thank you!!! this link is helpful.
davedrat
21 points
19 Posts
04-03-2009 9:47 AM |
Hi SLadapter,
Thanks for this link, I have implemented the code and it works well. I have one problem though...
It will only work when I have anonymous access permitted on the site which hosts the WCF Service.
For other reasons it is essential that my site has anonymous access disabled.
I assume that I have to change the BasicHttpMessageInspectorBinding to implement the equivalent of this:
<
</
But I am unclear how I would actually go about doing this in the context of the MessageInspector solution.
Any help would be gratefully received.
Cheers
04-03-2009 11:19 AM |
Davedrat,
Sorry I have never done this. I'm not sure you need to change anything in MessageInspector code;
You might just need to add the Security to the binding when you create BasicHttpMessageInspectorBinding. However, I have not figure out how to specify the transport in the code.
EndpointAddress address = new EndpointAddress(new Uri(Application.Current.Host.Source, "../Service.svc")); BasicHttpMessageInspectorBinding binding = new BasicHttpMessageInspectorBinding(new SilverlightFaultMessageInspector()); binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; // How to set the Transport here? // binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; This line won't work in Silverlight. ServiceClient proxy = new ServiceClient(binding, address); proxy.DoWorkCompleted += new System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(proxy_DoWorkCompleted); proxy.DoWorkAsync();
You might want to ask this question in the codeplex site where you download the sample code and see if the creator of this solution can provide an answer.
04-06-2009 4:57 AM |
Thanks for your quick reply sladapter,
The approach you describe seems like the right one... but I'm getting stuck at the same point as you.
There is an additional difficulty though.. If I do not change anything in the Message Inspector code, or the service web.config, then Visual Studio will not even let me add the service reference to my client Silverlight app.
VS complains that "Security Settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service."
Any thoughts on this?
I have contacted the codeplex guys to see if they can provide some help. If a solution is found I'll post it back here....
minus34
12 points
07-15-2009 3:41 AM |
Your issue is caused by Silverlight not supporting Windows Authentication. Hence a WCF service for a Silverlight app can't support Window Authentication...
It'd be nice if there was some workaround for this... But I've not heard of any.
Cheers,
Hugh