I have a Silverlight application that communicates to a Silverlight-enabled WCF service, both of which are under my control as a developer.
What are some of the best practices for handling exceptions that may occur in the WCF Service.
If you simply try to throw an exception in your WCF service, the exception information does not make it back to the Silverlight client. Instead, the Silverlight client receives a generic (and misleading) "Not Found" exception.
My service methods often return specific class objects. I have thought of a few approaches, but would love to get alternatives.
Add Exception type properties to your custom class objects and check properties of returned value.
Create a generic wrapper class that all methods return, that have transaction details (and exception details), as well as an attached return value object that can be any object type.
I did read something about modifying the WCF service to return detailed error information in the event of an exception (versus the unhelpful "not found"), but the article was incomplete and so I am still not sure that would work.
Thanks
Silverlight 4.0 does support the notion of Fault Contracts, but in order for exception details to be accessible in your client fault messages need to be returned with a HTTP 200 response. The following gives all the details (take a look under the heading Configuring WCF SOAP Faults for Use with Silverlight Clients):
http://msdn.microsoft.com/en-us/library/ee844556(VS.95).aspx
In terms of best practices take a look at the web service architecture guidelines of the Web Service Software factory:
http://msdn.microsoft.com/en-us/library/ff699426.aspx
Specifically, the topic on Exception Handling:
http://msdn.microsoft.com/en-us/library/ff699460.aspx
These guidances are all provided from the POV of WCF implementations...
Check out that link to trap the "Not Found" error :
http://blogs.runatserver.com/lppinson/post/2010/04/15/Debugging-WCF-Web-Services.aspx
Related
I need to calculate distances for some logic within a web service and assume google.maps API is appropriate. Everything I've seen is Jscript and requires a reference to the script in html tags <script>, which does not apply here. A .dll would make things obvious to me, but that does not seem to be available...
How do you access google.maps within a c# .asmx??
You will have to do the same thing that would be done by the JavaScript code you're seeing as examples. You'll want to use the WebClient class or maybe the WebRequest class to do the network I/O, but you've got to send and receive HTTP messages.
"Add Service Reference" won't work, of course.
Note that this problem is not specific to ASMX web services. You would have the exact same issue in a console program or Winforms application.
I have a WPF app that will show youtube videos on my tv via a media center pc. This app will receive commands to PlayVideo(string VideoId), PauseVideo(), etc via a WCF service hosted inside the WPF app.
This is a newbie question, but why can my MainWindow not implement the service contract and then be used as the service using the new ServiceHost() constructor that takes an object singleton in?
When I try I get this exception:
System.InvalidOperationException: Service 'Desktop.MainWindow' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.
My reasoning for doing this is that the simple commands needs to end up at the window anyway, so why not just have the window receive the messages directly instead of indirectly via subscribing to events on the service or having the service have a reference to the MainWindow and call methods on it.
The error, System.InvalidOperationException: Service 'Desktop.MainWindow' has zero application , simply means your app.config (if you have one) does not have the endpoints or the A,B,C's setup correctly (address, binding, contract).
You can host a wcf service in a winform or wpf form, you would only want to do that maybe for a test project in some kind of proof of concept work but never in an application you plan to give to a client or a real user.
If you're new to WPF I strongly recommend reading up on the Model-view-view-Model design pattern. This will allow you to implement the WCF service abstracted away from the UI in your WPF app and will give you a better separation of concerns and responsibilities for the logic in your app.
If you were writing code that others were going to maintain then I'd say...
Why not? Because you're mixing areas of responsibility. The Main Window doesn't need to know anything about WCF, it's job is to present things on screen.
Given that it's your app for your own personal needs, nobody cares what structure you use (just don't ask someone else to maintain it!) :) Having said that, if you want to make it easy for yourself to modify, I'd suggest making an effort to keep the code clean. What you're aiming to do, in my view, doesn't fit that description.
Your mainwindow probably could implement that Service Contract, but I think it's a very bad idea.
I am using a WCF service between the Client side UI (Silverlight 3.0) and the Data Layer. We are using NHibernate for Database Access. So please tell me if my below understanding is correct or not:
UI calls WCF for a Save Method (for eg).
The WCF has a Save method in it which actually encapsulates a Save method from the Data
Access Object.
The Data Access Object method of Save in turn encapsulates a default Save Method of
NHibernate which actually saves some Business Object/s into the Database.
Also can someone tell me that how do we pass objects from WCF to the UI (Silverlight 3.0) layer and vice versa. I have read that we use DTO for that. But how does a DTO work? Do they correspond to the 'Data Contracts' in the WCF? If not then is the DTO declared on WCF (server) side and Client side code as well?
No, not quite....
UI calls the client-side proxy method Save
the WCF runtime takes that call and all parameters being passed in, and serializes them into a message (typically a XML serialized message)
the WCF runtime sends the serialized message over some kind of a transport media (whatever it is)
on the server side, the WCF runtime takes the incoming message
the message is deserialized, the appropriate class and method to handle it are identified
typically: a new instance of a service class is instantiated to handle the request
the WCF runtime unpacks the parameters and calls that appropriate message on the service class
same steps - basically backwards - are done for response
Important point: the only thing between the client and the server is a serialized message (which could be sent by e-mail or pigeon courier) - there's no other connection - no "remote object call" or anything like that at all
marc_s mentions the client-side proxies, which can be generated via the service references in your Silverlight project. The generated proxies are decent enough and provide an async model for running requests from the Silverlight side; those will look mostly like remoted procedure calls.
Another approach is to use the leaner (but maybe more advanced?) channel factory directly. A simple example of that can be found here. Both methods take care of most of the serialization details for you.
What is the correct way of handling errors on the client side of Silverlight applications? I tried building a service endpoint that would receive details about the error and then would write that string to the database. The problem is, the error's text exceeds the maximum byte length, so I can't send the exception message and stacktrace. What would be a better way of handling errors that end up at the client side?
Try handling faults...I used this pattern from MSDN
http://msdn.microsoft.com/en-us/library/dd470096%28VS.96%29.aspx
If you find you message is too long to send to your logging web service then try setting your binding properties such as maxBufferSize and maxStringContentLength to appropriately large values. They default to 16KB, personally i have set mine to 2147483647 (which is int.MaxValue).
Obviously you cannot send the raw exception straight to the logging web service (exceptions are not serializable), what i did was write a function that takes an exception and walks it, translating it into a WCF friendly structure that can then be passed to my logging end point. Of course you need to ensure that if this fails you have a backup plan, like maybe logging it to isolated storage if you are running in browser, or logging it to the user's file system if you are running elevated OOB.
You should not be considering logging of error messages via a service. What if the error that you want to log is related to the service itself? Maybe the server that hosts all dependant services (including the error logging service) is not reachable or down. client errors should be logged on the client side and periodically flushed to the server when connectivity to service is available.
Thats what I would do...
Take a look at the new Silverlight Integration Pack for Enterprise Library from Microsoft patterns & practices. It provides plumbing for both logging (client-side and via a remote service) and exception handling with flexible configuration of policies via config or programmatically.
In ASP.NET, I usually log exceptions at server-side, In windows forms I can either log exceptions server-side or write to a log file on the client. Silverlight seems to fit somewhere in between.
I wanted to know what everyone else is doing to handle their Silverlight exceptions and I was curious if any best practices have emerged for this yet.
For real logging that you could store & track, you will need to do it on the server, since you can't be guaranteed anything on the client will be persisted.
I would suggest exposing a "LogEvent(..)" method on a server side web service (maybe you already have one) which would then do the same kind of logging you do in ASP.net
Here's a video about basic web service calls in Silverlight if you haven't done that yet
http://silverlight.net/learn/learnvideo.aspx?video=66723
I'm not sure about any logging best practices though, my first guess would be to do the best practicies for logging in a web sevice on the server and expose that to the client.
Hope this helps!
I would say that Silverlight fits much better to ASP.NET side of the model. You have server which serves web page. An object (Silverlight app) on the page pings data service to fetch data and display it.
All data access happens on the server side and it does not matter if data is used to create ASP.NET pages on the server or sent raw to the RIA for display. I do log any failures in data service on server side (event log works fine) and do not allow any exception to pass to WCF. When client does not receive expected data (it gets null collection or something similar), it display generic data access error to the user. We may need to extend that soon to pass a bit more information (distinguishing between access denied/missing database/infrastructure failure/internal error/etc), but we do not plan to pass exception error messages to the client.
As for client side, sometimes we may get in situation where async call times out -- it is just another message. For general exceptions from client code (typically, bugs in our code), I just pass exception to the browser to display in same manner as any script exception.
Also take a look at the new Silverlight Integration Pack for Enterprise Library from Microsoft patterns & practices. It provides support for logging exceptions to isolated storage or remote services and is configurable via policies in external config or programmatically. Batch logging and automatic retry (in case of occasionally connected scenarios) are also supported.
Use the Isolated Storage available for Silverlight application. You should store here your log.
Then you can develop a mecanism to send the user log to a webservice like the Windows bug report service.
It very much depends on the type of application that youre developing.
if its an mvc / mvp based architecture then your model, or most of it at least, will be on the server, and this is where most of your exceptions will be thrown i would imagine, so you can log them there and choose to display a message to the user or not.
for exceptions from the client you may want to know the details so just send them back.