Archive

Archive for the ‘Silverlight’ Category

Alternatives to Throwing Exceptions to Flex/Silverlight Clients From a .NET Web Service – part 2

February 7th, 2009 joelhainley No comments

In part 1 of this article I argued that exceptions sent “over the wire” to flex/silverlight clients from a webservice weren’t necessarily the right way to put things together. I argued that that exposing your clients to raw exceptions happening in your server was not elegant in the same way that throwing raw exceptions to a user in a windows desktop app was not elegant. In talking about the last article with some people I realized that I needed to make a point. There are times when an exception is appropriate, and I’m not advocating avoiding exceptions altogether. My point was that I felt people were relying on exceptions too heavily when a more appropriate method might be possible.

Let’s take a look at input validation to see what we mean about relying too heavily on exceptions. Validation is a bear, you want to try and have your validation rules in one spot only. This way you can avoid the chore of duplicating validation logic on the client and the server. This seems to be one of the main reasons people are looking at bubbling exceptions over the wire because if they can simply put the validation logic in the server side, then they can throw an exception back to the client and deal with it there. It solves the the problem of duplication of validation logic and allows developers to deal with validation errors in the same way that they do within desktop application environments.

The question now becomes can we avoid exceptions and still provide for a rich validation environment? I believe that we can and I’m going to spend the rest of this article describing an approach. It may not be the best approach, it may not be the only approach, but it was worked well for me on the last few projects and enough people I’ve talked to about the approach seem to feel that it’s powerful enough to consider for their future efforts along these lines.

In order to provide a framework upon which to hang our theory let’s consider a simplified method of a web service named “CreateAccount” that takes as it’s only parameter an Account object.

Account UML

When we want to create a new account we will fill out the information about the account as described and then pass it to the CreateAccount method of the webservice. However, instead of just having a void for the return value and throw exceptions if there are errors you simply use a response object such that the method signature would look something like the following :

CreateAccountResponse  CreateAccount( Account acct)

This is certainly not a new concept. Response objects litter many namespaces, but in this particular situation they allow us to avoid having a lot of exceptions flying out of our webservice and doing all sorts of ridiculous plumbing hacks to get it all to operate nicely.  Now let’s take a quick look at the CreateAccountResponse class and see what it looks like, then we can talk about how a response object allows us to avoid duplicate validation and exceptions. Below is the UML for the CreateAcountResponse object

We see that this class mmics the Account class pretty closely with the addition of a couple of routines that would be needed to actually communicate results. The Success flag would indicate whether the account creation was successful and the error message would only be filled out if there was a particular error that you wanted to communicate to the user such as “You do not have the rights to create accounts” or something along those lines. The other fields would be filled out if there were problems with the validation of the individual fields of the account object. This would allow us to have all of the validation/error messages specified on the server side in a single location and still be able to get the information out to your users. Such that if you require the state field to be only 2 characters long and someone puts in 4 you could set the success flag to false and then add error text to the State field of the response object that could then be displayed to the end user.

WIth this approach if there was an exception generated in the webservice, we could trap it server side and provide the appropriate message to the CreateAccountResponse object and not have to require the client to exception handling just to know what is happening.

Now one of the complaints  that I have heard about this approach is “but now you have to create all of these response objects”. Well yeah, but one way or another you’re going to have to write some code to deal with errors and wouldn’t it be nice if you could deal with the errors and the error messages in a single place? Also you could simply create a generic results object that would suffice for most of the calls that you want to make. Then again consider that in some of the more mature environments such as .NET WebServices  you can easily create webservices that provide this sort of functionality and the WSDL’s and whatnot are all created for you.So it’s not nearly as much work to do this as it could be.

What about the overhead of all of these custom classes? Is it really any more overhead than the throwing of exceptions? Exception throwing, and handling are expensive operations. I find it a little be cleaner to my thinking because now you have a clear and concise definition of what you need to program against when you are dealing with your WebService’s API.

I’m not saying this is necessarily the best approach for all occassions, and I’m not really down on exceptions in general, or even for web services. However I think that there are many times when the extra effort you have to go through just to get robust exception handling done will lead you into a lot of needless efforts. Especially if you are just trying to provide validation/failure information back to the client applications.Keep in mind that what I’ve presented here isn’t a blueprint, it’s more like a pattern of how you might consider structuring your webservices in certain situations.

Your mileage may vary.

Silverlight : Communication Exception was unhandled by user code

February 4th, 2009 joelhainley 4 comments

Ran into the following error the other day :

An error occurred while trying to make a request to URI ‘http://localhost/T2WS/AdminServices.asmx’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. Please see the inner exception for more details.

The error message was self-explanatory but it didnt’ solve the problem. I had my cross domain file setup appropriately and yet I was still receiving the error. As seen below the stack trace didn’t offer much help either:

System.ServiceModel.CommunicationException was unhandled by user code
Message=”An error occurred while trying to make a request to URI ‘http://localhost/T2WS/AdminServices.asmx’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. Please see the inner exception for more details.”
StackTrace:
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.ClientBase`1.ChannelBase`1.EndInvoke(String methodName, Object[] args, IAsyncResult result)
at T2SL.T2AdminService.AdminServicesSoapClient.AdminServicesSoapClientChannel.EndgetAccountList(IAsyncResult result)
at T2SL.T2AdminService.AdminServicesSoapClient.T2SL.T2AdminService.AdminServicesSoap.EndgetAccountList(IAsyncResult result)
at T2SL.T2AdminService.AdminServicesSoapClient.EndgetAccountList(IAsyncResult result)
at T2SL.T2AdminService.AdminServicesSoapClient.OnEndgetAccountList(IAsyncResult result)
at System.ServiceModel.ClientBase`1.OnAsyncCallCompleted(IAsyncResult result)
InnerException: System.Security.SecurityException
Message=”"
StackTrace:
at System.Net.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
InnerException: System.Security.SecurityException
Message=”Security error.”
StackTrace:
at System.Net.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
InnerException:

Still no luck, i spent some time fiddling with the clientaccesspolicy.xml file but it didn’t seem to be the problem. After a bit of digging and avoiding the obvious, it finally hit me right between the eyes. I had setup the Silverlight project to be the startup and it was running the file locally, instead of running it through the web project I had setup to wrap Silverlight with.

Once I changed the startup project to the Web project and the file to the Silverlight testpage everything worked just fine and dandy except that the Silverlight project wasn’t updating. Looking through the Silverlight project properties I was able to point the build for the Silverlight “executable” to the Web project’s ClientBin directory and everything fell into place.

I just mention this hear because I’m sure I’ll forget how I solved this problem the next time I run into it. ;-)