Calling Web Services to Validate Data in Visual Studio LightSwitch
Very often in business applications we need to validate data through another service. I’m not talking about validating the format of data entered – this is very simple to do in LightSwitch -- I’m talking about validating the meaning of the data. For instance, you may need to validate not just the format of an email address (which LightSwitch handles automatically for you) but you also want to verify that the email address is real. Another common example is physical Address validation in order to make sure that a postal address is real before you send packages to it.
In this post I’m going to show you how you can call web services when validating LightSwitch data. I’m going to use the Address Book sample and implement an Address validator that calls a service to verify the data.
Where Do We Call the Service?
In Visual Studio LightSwitch there are a few places where you can place code to validate entities. There are Property_Validate methods and there are Entity_Validate methods. Property_Validate methods run first on the client and then on the server and are good for checking the format of data entered, doing any comparisons to other properties, or manipulating the data based on conditions stored in the entity itself or its related entities. Usually you want to put your validation code here so that users get immediate feedback of any errors before the data is submitted to the server. These methods are contained on the entity classes themselves. (For more detailed information on the LightSwitch Validation Framework see: Overview of Data Validation in LightSwitch Applications)
The Entity_Validate methods only run on the server and are contained in the ApplicationDataService class. This is the perfect place to call an external validation service because it avoids having clients calling external services directly -- instead the LightSwitch middle-tier makes the call. This gives you finer control over your network traffic. Client applications may only be allowed to connect to your intranet internally but you can allow external traffic to the server managing the external connection in one place.
Calling Web Services
There are a lot of services out there for validating all sorts of data and each service has a different set of requirements. Typically I prefer REST-ful services so that you can make a simple http request (GET) and get some data back. However, you can also add service references like ASMX and WCF services as well. It’s all going to depend on the service you use so you’ll need to refer to their specific documentation.
To add a service reference to a LightSwitch application, first flip to File View in the Solution Explorer, right-click on the Server project and then select Add Service Reference…
Enter the service URL and the service proxy classes will be generated for you. You can then call these from server code you write on the ApplicationDataService just like you would in any other application that has a service reference. In the case of calling REST-ful services that return XML feeds, you can simply construct the URL to call and examine the results. Let’s see how to do that.
Address Book Example
In this sample we have an Address table where we want to validate the physical address when the data is saved. There are a few address validator services out there to choose from that I could find, but for this example I chose to sign up for a free trial of an address validation service from ServiceObjects. They’ve got some nice, simple APIs and support REST web requests. Once you sign up they give you a License Key that you need to pass into the service.
A sample request looks like this:
Which gives you back the result:
<?xml version="1.0" encoding="UTF-8"?>
<Address xmlns="https://www.serviceobjects.com/"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<Address>1 Microsoft Way</Address>
<City>Redmond</City>
<State>WA</State>
<Zip>98052-8300</Zip>
<Address2/>
<BarcodeDigits>980528300997</BarcodeDigits>
<CarrierRoute>C012</CarrierRoute>
<CongressCode>08</CongressCode>
<CountyCode>033</CountyCode>
<CountyName>King</CountyName>
<Fragment/>
</Address>
If you enter a bogus address or forget to specify the City+State or PostalCode then you will get an error result:
<?xml version="1.0" encoding="UTF-8"?>
<Address xmlns="https://www.serviceobjects.com/"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<Error>
<Desc>Please input either zip code or both city and state.</Desc>
<Number>2</Number>
<Location/>
</Error>
</Address>
So in order to interact with this service we’ll first need to add some assembly references to the Server project. Right-click on the Server project (like shown above) and select “Add Reference” and import System.Web and System.Xml.Linq.
Next, flip back to Logical View and open the Address entity in the Data Designer. Drop down the Write Code button to access the Addresses_Validate method. (You could also just open the Server\UserCode\ApplicationDataService code file if you are in File View).
First we need to import some namespaces as well as the default XML namespace that is returned in the response. (For more information on XML in Visual Basic please see: Overview of LINQ to XML in Visual Basic and articles here on my blog.) Then we can construct the URL based on the entity’s Address properties and query the result XML for either errors or the corrected address. If we find an error, we tell LightSwitch to display the validation result to the user on the screen.
Imports System.Xml.Linq
Imports System.Web.HttpUtility
Imports <xmlns="https://www.serviceobjects.com/">
Namespace LightSwitchApplication
Public Class ApplicationDataService
Private Sub Addresses_Validate(entity As Address, results As EntitySetValidationResultsBuilder)
Dim isValid = False
Dim errorDesc = ""
'Construct the URL to call the web service
Dim url = String.Format("https://trial.serviceobjects.com/av/AddressValidate.asmx/ValidateAddress?" &
"Address={0}&Address2={1}&City={2}&State={3}&PostalCode={4}&LicenseKey={5}",
UrlEncode(entity.Address1),
UrlEncode(entity.Address2),
UrlEncode(entity.City),
UrlEncode(entity.State),
UrlEncode(entity.ZIP),
"12345")
Try
'Call the service and load the XML result
Dim addressData = XElement.Load(url)
'Check for errors first
Dim err = addressData...<Error>
If err.Any Then
errorDesc = err.<Desc>.Value
Else
'Fill in corrected address values returned from service
entity.Address1 = addressData.<Address>.Value
entity.Address2 = addressData.<Address2>.Value
entity.City = addressData.<City>.Value
entity.State = addressData.<State>.Value
entity.ZIP = addressData.<Zip>.Value
isValid = True
End If
Catch ex As Exception
Trace.TraceError(ex)
End Try
If Not (isValid) Then
results.AddEntityError("This is not a valid US address. " & errorDesc)
End If
End Sub
End Class
End Namespace
Run it!
Now that I’ve got this code implemented let’s enter some addresses on our contact screen. Here I’ve entered three addresses, the first two are legal and the last one is not. Also notice that I’ve only specified partial addresses.
If I try to save this screen, an error will be returned from the service on the last row. LightSwitch won’t let us save until the address is fixed.
If I delete the bogus address and save again, you will see that the other addresses were verified and all the fields are updated with complete address information.
Wrap Up
I hope this gives you a good idea on how to implement web service calls into the LightSwitch validation pipeline. Even though each service you use will have different requirements on how to call them and what they return, the LightSwitch validation pipeline gives you the necessary hooks to implement complex entity validation easily.
Enjoy!
Comments
Anonymous
February 04, 2012
Thanks for the article. I would be extremely grateful for an article demonstrating the calling of a web service viaa button click here. The button click code is understood. Getting a WSDL service (which can only be implemented in the server) to be called by a button is a mystery though. I have been down the WCF RIA path...you can read about that plight here: social.msdn.microsoft.com/.../3a547ac4-5ed2-49f0-82bf-873925335a81Anonymous
February 09, 2012
Perhaps a look at a walkthough I uploaded: code.msdn.microsoft.com/LightSwitch-Consuming-Web-c54979e0 may be of interest.Anonymous
August 13, 2012
Thank You The given information is very effective i will keep updated with the same <a href ="http://www.agrimawebservices.com">web services</a>Anonymous
September 03, 2012
The comment has been removedAnonymous
September 12, 2012
LightSwith 2012 can not be Imports System.Xml.Linq Imports System.Web.HttpUtility I have added a reference System.xml.linq System.Web Please help!Anonymous
October 17, 2014
Thanks Beth for the referral to Service Objects! Let me know if you'd like a new API testing key. :)Anonymous
October 17, 2014
Thanks again Beth and here is the link for all of our data quality APIs. www.serviceobjects.com/productsAnonymous
February 10, 2017
Why users still use to read news papers when in this technological globe all is accessible on net?