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…

image

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:

https://trial.serviceobjects.com/av/AddressValidate.asmx/ValidateAddress?Address=One+Microsoft+Way\&Address2=\&City=Redmond\&State=WA\&PostalCode=98052\&LicenseKey=12345

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.

image

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).

image

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.

image

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.

image

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.

image

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!