Create a C# Client App in Visual Studio

Welcome to Verizon M2M client application development!

This tutorial teaches you how to build your first M2M client application using C# in Microsoft Visual Studio. The application will log in to create an API session, use the session token to activate a device and retrieve information about the device, and then log out to terminate the session. You’ll learn some fundamentals of working with SOAP in C#, and how to send requests to our web services and receive synchronous responses. (Some M2M API methods also send asynchronous responses, and there is a separate tutorial covering how to receive those responses.)

Create Clean Code with SOAP

The Verizon Wireless Network Services API uses SOAP messages in XML format to communicate with your client application. SOAP is a communication protocol that is based on XML, so it can be used on any platform and with any programming language, including C#.

Learn about SOAP and web services:

If this is your first time working with SOAP or XML, don't worry -- you'll only be working with local C# classes and objects. There are standard C# libraries that convert XML messages to C# objects and vice-versa, and the Wireless Network Services SDK includes some common methods and client proxies for all Wireless Network Services web services. You don't need to know how to read XML, and you certainly don't need to be a SOAP expert.

This tutorial will walk you through the steps required to use those C# tools, load the M2M web service descriptions into your project, and use the M2M classes and methods to accomplish some common tasks, including:

There is a separate tutorial that covers creating a listening service for asynchronous callback messages from the ThingSpace Platform, and registering to receive those messages.

Before You Start This Tutorial

You're probably ready to jump right in and get started, but there are some preparatory steps that you have to take before you can write an application to communicate with the ThingSpace Platform web services.

Know your company's Verizon M2M account name and API login credentials.
This is a special username and password that can only be used to authenticate for API sessions. Contact your Verizon Wireless business sales representative to obtain these credentials.
Get your outgoing IP address on our white list.
As part of our security strategy, the ThingSpace Platform only responds to requests from IP addresses that are on the Verizon M2M Data Center white list. The computer that you use for this tutorial must be configured to send requests from that IP address. Contact your Verizon Wireless business sales representative for more information.
Have an M2M device available that you can add to your company's account and activate (this may be a test or a production account).
You will need to know the identifiers for the device and a service plan that it is compatible with. For 3G devices, you can use the ESN or MEID as device identifiers. For 4G devices, you must provide both the IMEI and ICCID identifiers.

You will not be able to create a functional M2M API client until you can check off all of these items.

Install the Software

Before you start this tutorial, you should have downloaded and installed:

Configure C# to Work with SOAP Web Services

Your client application will interact with web services on the ThingSpace Platform. Your application needs to know what those services are, where to connect with them, and what data can be sent and received.

The ThingSpace Platform web services are described in WSDL files, which are XML documents that conform to the Web Service Description Language. Each web service has its own WSDL file that specifies the location of the service and the operations (methods) that are available in the service. There are also some XSD schema documents that define the details of interacting with the service. The WSDL and schema files for all Verizon Wireless Network Services are included in the Verizon Wireless Network Services SDK.

To work with SOAP web services in your C# application, the WSDLs and schema documents have to be converted to C# classes and methods, and then added to your project. You can do this yourself by adding them as service references, but the SDK contains a ClientProxy project that already contains the C# classes created from the WSDL and XSD files, so that conversion is already done for you.

Create a Project and Add the M2M Common Library and Proxies

This tutorial uses a new project and solution to keep things clear. You can also do these steps in an existing project.

  1. Create a new C# Project. This example uses a Windows Console Application project, but you can use most types of projects.
  2. From the Tools and Examples folder in the Wireless Network Services SDK, open src.zip. Extract the folders CommonLib and ClientProxy.
  3. Back in Visual Studio, right-click the solution (not your project) and from the Add menu, select Existing Project.

  4. Navigate to where you placed the CommonLib folder, select CommonLib.csproj, and click Open. Click OK if Visual Studio prompts you about needing to modify the project in order to open it, and for any security warnings.

  5. Repeat steps 3 and 4 to add the ClientProxy project from the SDK.
  6. Build the entire solution.
  7. If you are using Visual Studio 2010, right-click on your project (not the solution) and select Properties. Set the Target Framework to ".Net Framework 4" (''not'' ".Net Framework 4 Client Profile"). You can also use a newer version of the .Net Framework. This may cause your project to close and reload.

  8. In your project, right-click on References and select Add Reference.

  9. In Visual Studio 2012 and 2013, select Assemblies > Framework. Check the checkboxes for these classes and then click OK:


    In Visual Studio 2010, click the .Net tab, then select these classes and click OK:

  10. In your project, right-click on References and select Add Reference again.
  11. In Visual Studio 2012 and 2013, select Solution > Projects, then check the checkbox for CommonLib and ClientProxy. Click OK.


    In Visual Studio 2010, click the Projects tab and select CommonLib and ClientProxy, and click OK.

Add the ServiceModel to app.config

The ClientProxy class library includes an app.config file that contains system.ServiceModel settings that are required to make connections to the M2M endpoints. You must copy the system.ServiceModel from that file and paste it into the app.config file in your project.

  1. Double-click the app.config file that is under ClientProxy to open it in the editor.
  2. Select and copy everything from the opening <system.serviceModel> tag to the closing </system.ServiceModel> tag, including those tags.
  3. Close the app.config file.
  4. Double-click the app.config file that is under your project to open it in the editor. (The file name may be capitalized as App.config.)
  5. Paste the copied <system.serviceModel> section just before the closing </configuration> tag.
  6. Save and close the app.config file.

Create Your SOAP Client App

Process Flow

When making calls to Wireless Network Services APIs, your application will follow this flow:

  1. Log in and receive a session token.
  2. Make other API requests, putting the session token in the header of each request.
  3. When all planned requests have been sent, log out to invalidate the session token.

Some requests take some time to process, such as activating a device or changing a service plan. For those requests, the ThingSpace Platform sends a synchronous response that acknowledges the request and allows your application to continue processing. Later, the platform sends an asynchronous callback message, reporting the results of the request. Working with M2M callback messages is covered in Create a C# Callback Listener in Visual Studio.

Log In and Get a Session Token

As part of ThingSpace Platform security, your application must include a valid session token in the header of all requests. To receive one, the application must log in, providing a valid username and password. The SOAP response will include a session token.

NOTE:Your application can use a token as many times as needed, but a session expires after 20 minutes of inactivity. If the ThingSpace Platform returns an error saying that the token is expired, your application will need to log in again to obtain a new token.

To log in to the ThingSpace Platform:

  1. Right-click on your project and select Add > Class to create a new class. In this example we named the class "Wns" for "Wireless Network Services."

  2. Add the following using statements before the namespace declaration, to work with SOAP web services.

    using CommonLib;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.Configuration;
    
  3. Add a using statement for the SessionServiceProxy that is part of the ClientProxy.

    using ClientProxy.SessionService;
    
  4. Create member variables to hold the session token and session service proxy.

    namespace M2MTutorial
    {
        class Wns
        {
            private string sessionToken;
            private SessionServiceClient sessionService;
    
  5. Create a login method with the code to log in and store the session token. (This tutorial uses Console.WriteLine() so that you can see your code working, but you normally would not need that line.)

            private void Login(string username, string password)
            {
                // Create a login request object that will make the API call. 
                // The LogInRequest class is autogenerated from the wsdl file.
                LogInRequest request = new LogInRequest();
    
                // Set the username and password for the request.
                request.Username = username;
                request.Password = password;
    
                // Create a SessionServiceClient object. The SessionServiceClient 
                // class is autogenerated from the wsdl file. 
                sessionService = new SessionServiceClient();
    
                // Add a behavior to the sessionService endpoint that will add
                // the session token to the header of all SessionService requests. 
                // The sessionToken value is added inside the try block.
                // This is a little more complex for the sessionService client than
                // for the other services.
                // AddSessionTokenToHeaderBehavior() comes from the CommonLib library.
    
                sessionService.Endpoint.Behaviors.Add(new AddSessionTokenToHeaderBehavior(""));
                //VS2013 version
                //sessionService.Endpoint.EndpointBehaviors.Add(new AddSessionTokenToHeaderBehavior(""));
    
                try
                {
                    // Pass the request object to the LogIn() method to 
                    // send the request and get the response.
                    LogInResponse response = sessionService.LogIn(request);
    
                    // The token is a string that you get from the response.
                    sessionToken = response.SessionToken;
                    Console.WriteLine("Log in successful. Session token is " + sessionToken);
    
                    // Set the session token for the AddSessionToTokenBehavior in the endpoint.
                    var requestHeader = sessionService.Endpoint.Behaviors.First(b => b is AddSessionTokenToHeaderBehavior);
                    ((AddSessionTokenToHeaderBehavior)requestHeader).SessionToken = response.SessionToken;
    
                }
                // The service will return SOAP faults as fault exceptions, 
                // such as for an invalid password
                catch (FaultException ex)
                {
                    Console.WriteLine("FaultException:" + ex.Message);
                }
                // The service can throw a timeout exception (for instance, if the 
                // SessionServiceClient endpoint address is not correct).
                catch (System.TimeoutException ex)
                {
                    Console.WriteLine("TimeoutException:" + ex.Message);
                }
            }
    
  6. Finally, create the main() method to call Login(). Replace "username" and "password" with the UWS username and password for your account.

            static void Main(string[] args)
            {
                Wns session = new Wns();
                session.Login("username", "password");
            }
    

    NOTE:If you created a new project for this tutorial, you will need to delete the program.cs file, or at least delete its main() method, since a project can't have two main() methods.

  7. If you created your project as a Console Application, press Ctrl+F5 to run the code in debug mode, which will leave the console window open so that you can see the output.

Log Out

As a security measure, your application should log out of the ThingSpace Platform when finished making requests. Logging out will invalidate the current session token, ensuring that it can't be used for any further requests.

The LogOut request must contain the session token in the header as well as in the body element. The token is added to the request header automatically because Logout() uses the Session Service client that was created by Login(). The ThingSpace Platform verifies the token, invalidates the session, and then returns the same token in the response.

  1. Add a logout method that uses the SessionServiceClient object that was created at login.

            private void Logout()
            {
                // Add a behavior that adds the session token to all requests.
                sessionService.Endpoint.Behaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
                // VS2013 version
                // sessionService.Endpoint.EndpointBehaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
    
                LogOutRequest request = new LogOutRequest();
                request.SessionToken = sessionToken;
    
                try
                {
                    // Send the request using the SessionServiceClient object
                    // created at login.
                    LogOutResponse response = sessionService.LogOut(request);
                    Console.WriteLine("Session " + response.SessionToken + " terminated.");
                }
                catch (FaultException ex)
                {
                    Console.WriteLine("FaultException:" + ex.Message);
                }
                catch (System.TimeoutException ex)
                {
                    Console.WriteLine("TimeoutException:" + ex.Message);
                }
            }
    
  2. Call the new method from main().

            static void Main(string[] args)
            {
                Wns session = new Wns();
                session.Login("username", "password");
                session.Logout();
            }
    
  3. Press Ctrl+F5 to run the code in debug mode.

Activate a Device

Activating service for a device prepares a device for use on the Verizon network, including adding the device to the account (if it's not added already) and assigning a phone number (MDN/MSISDN). Once activated, a device can send and receive data on the network.

Activating a device is an asynchronous operation that uses CarrierService callbacks to notify you when the activation is complete. Activation usually only takes a few minutes, but can take up to 24 hours to complete. There is a separate tutorial that covers creating a listening service for M2M callback messages and registering to receive those messages.

You must provide a valid service plan code when activating a device so that the service can be billed correctly. This tutorial includes code for getting a list of service plans in the account, and then simply uses the first service plan code that is returned in the response. You will probably want something a little more sophisticated in your production application.

  1. Service plans belong to accounts, and device activation is part of the carrier service, so you need to add using statements for the AccountService and CarrierService classes in ClientProxy.

    using ClientProxy.AccountService;
    using ClientProxy.CarrierService;
    
  2. Create a method to get the code for the first service plan in the account.

            private string GetServicePlanCode(String account)
            {
                // Create an AccountServiceClient object.
                AccountServiceClient accountService = new AccountServiceClient();
    
                // Add a behavior that adds the session token to all requests.
                accountService.Endpoint.Behaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
                // VS2013 version
                // accountService.Endpoint.EndpointBehaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
    
                // Create a request object and set your account name as an attribute.
                GetServicePlanListRequest request = new GetServicePlanListRequest();
                request.Account = account;
    
                try
                {
                    // Send the request.
                    GetServicePlanListResponse response = accountService.GetServicePlanList(request);
    
                    // Store the first service plan object.
                    ServicePlan servicePlan = response.ServicePlans[0];
    
                    // For tutorial, display success message.
                    Console.WriteLine("Using service plan " + servicePlan.Name + " with code " + servicePlan.Code);
    
                    // Return the service plan code.
                    return servicePlan.Code;
                }
                catch (FaultException ex)
                {
                    Console.WriteLine("FaultException:" + ex.Message);
                    return "00000";
                }
                catch (System.TimeoutException ex)
                {
                    Console.WriteLine("TimeoutException:" + ex.Message);
                    return "00000";
                }
            }
    
  3. To activate a device, you must include identifiers for the device, such as the ICCID (for the SIM card) or the IMEI, ESN, or MEID of the device itself. To activate a 4G device, you must use both the IMEI and the ICCID, in that order. This tutorial uses the two identifiers for a 4G device.

            private void ActivateDevice(string account, string svcPlanCode)
            {
                // Create a CarrierServiceClient object.
                CarrierServiceClient carrierService = new CarrierServiceClient();
    
                // Add the session token from login to the header.
                carrierService.Endpoint.Behaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
                // VS2013 version
                // carrierService.Endpoint.EndpointBehaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
    
                // Create the two Device Identifier objects required for a 4G device.
                // You must use the fully qualified name for the DeviceIdentifier class because
                // DeviceService and CarrierService both have DeviceIdentifier classes
                ClientProxy.CarrierService.DeviceIdentifier deviceId1 = new ClientProxy.CarrierService.DeviceIdentifier();
                deviceId1.Kind = "imei";
                deviceId1.Identifier = "990003420535574";
                ClientProxy.CarrierService.DeviceIdentifier deviceId2 = new ClientProxy.CarrierService.DeviceIdentifier();
                deviceId2.Kind = "iccid";
                deviceId2.Identifier = "89148000000800784258";
    
                // Put the Device Identifier objects into a list of identifiers.
                var deviceIds = new List { deviceId1, deviceId2 };
    
                // Create a DeviceIdentifierCollection object to hold the list of device identifiers.
                ClientProxy.CarrierService.DeviceIdentifierCollection deviceIdCollection = new ClientProxy.CarrierService.DeviceIdentifierCollection();
                deviceIdCollection.DeviceIdentifiers = deviceIds;
    
                // Create a list of DeviceIdentifierCollection objects to pass to ChangeDeviceState.
                // This is the list of all devices to be changed (only one in this case).
                var deviceList = new List { deviceIdCollection };
    
  4. You use the ChangeDeviceStateRequest in the CarrierService to make any device state changes. The request has an ActivateDeviceRequest object as a property. (It also has properties for suspending, deactivating, and restoring devices.) The ActivateDeviceRequest object contains properties for the service plan code and the MDN Zip code, which is the Zip code where you expect the device to be used the most. Add the following code under the code you just added. The Zip code is set to 98115.

                // Create request to change the device state.
                ChangeDeviceStateRequest cdsRequest = new ChangeDeviceStateRequest();
                cdsRequest.Activate = new ActivateDeviceRequest();
                cdsRequest.AccountName = account;
                cdsRequest.DeviceList = deviceList; //list of devices
                cdsRequest.Activate.ServicePlan = svcPlanCode;
                cdsRequest.Activate.MdnZipCode = "98115";
    
  5. Send the request, and save the returned Request ID to match up with the callback message.

                try
                {
                    // Make the request to activate.
                    ChangeDeviceStateResponse cdsResponse = carrierService.ChangeDeviceState(cdsRequest);
    
                    // Store the returned request ID for later use.
                    string requestId = cdsResponse.RequestId;
    
                   // For tutorial, display request ID.
                   Console.WriteLine("Activate request acknowledged with request ID " + requestId);
    
                }
                catch (FaultException ex)
                {
                    Console.WriteLine("FaultException:" + ex.Message);
                }
                catch (System.TimeoutException ex)
                {
                    Console.WriteLine("TimeOutException:" + ex.Message);
                }
    
            }
    
  6. Finally, call the new methods from main(). Pass in the name of your account to both of the new methods.

            static void Main(string[] args)
            {
                Wns session = new Wns();
                session.Login("username", "password");
                String servicePlanCode = session.GetServicePlanCode("account");
                session.ActivateDevice("account", servicePlanCode);
                session.Logout();
            }
    
  7. Press Ctrl+F5 to run the code in debug mode.
  8. Retrieve All Information about a Device

    After your application has received the callback message indicating that the device activation is complete, you may want to pull all of the information about the device and add it to your local database of devices. For example, your application can parse the returned information to find the phone number that was assigned to the device. The following code requests the information for a device and checks the state and MDN/MSISDN value.

    NOTE:Because activation can take some time, do not create your application to make an activation request and then immediately check the device information. The device state will not change until after the asynchronous callback has been sent. Best practice is to wait until after receiving the callback before checking the device information.

    1. Add a using statement for the DeviceService class that is part of ClientProxy.

      using ClientProxy.DeviceService;
      
    2. Add a method to request the device information.

              private void GetDvcInformation()
              {
      
                  // Create a DeviceServiceClient object.
                  DeviceServiceClient deviceService = new DeviceServiceClient();
      
                  // Add a behavior that adds the session token to all DeviceService requests.
                  deviceService.Endpoint.Behaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
                  // VS2013 version
                  // deviceService.Endpoint.EndpointBehaviors.Add(new AddSessionTokenToHeaderBehavior(sessionToken));
      
                  // Create a device information request.
                  GetDeviceInformationRequest gdiRequest = new GetDeviceInformationRequest();
      
                  // Use the IMEI of the device you activated as the device ID.
                  // Note that 4G devices only need two identifiers when activating,
                  // so one is enough here.
                  ClientProxy.DeviceService.DeviceIdentifier deviceId = new ClientProxy.DeviceService.DeviceIdentifier();
                  deviceId.Kind = "imei";
                  deviceId.Identifier = "990003420535573";
                  gdiRequest.Device = deviceId;
      
                  try
                  {
                      GetDeviceInformationResponse gdiResponse = deviceService.GetDeviceInformation(gdiRequest);
                  }
                  catch (FaultException ex)
                  {
                      Console.WriteLine("FaultException:" + ex.Message);
                  }
                  catch (System.TimeoutException ex)
                  {
                      Console.WriteLine("TimeOutException:" + ex.Message);
                  }
      
              }
      
    3. Inside the try statement, add code to find the device state and assigned MDN/MSISDN.

                  try
                  {
                      GetDeviceInformationResponse gdiResponse = deviceService.GetDeviceInformation(gdiRequest);
      
                      // The device state is contained in the CarrierInformation
                      String dvcState = gdiResponse.Device.CarrierInformation[0].State;
                      Console.WriteLine("Device state is " + dvcState);
      
                      // If the device is active, get the MDN/MSISDN assigned by the network.
                      if (dvcState.Equals("active"))
                      {
                          foreach (ClientProxy.DeviceService.DeviceIdentifier dvcId in gdiResponse.Device.DeviceIdentifiers) 
                          {
                              if (((dvcId.Kind.Equals("mdn")) | (dvcId.Kind.Equals("msisdn"))))
                              {
                                  // You probably want to record the phone number,
                                  // but here we'll just display it.
                                  Console.WriteLine(dvcId.Kind + " is " + dvcId.Identifier);
                              }
                          }
                      }
      
    4. Call the new method from main().

              static void Main(string[] args)
              {
                  Wns session = new Wns();
                  session.Login("username", "password");
                  String servicePlanCode = session.GetServicePlanCode("account");
                  session.ActivateDevice("account", servicePlanCode);
                  session.GetDvcInformation();
                  session.Logout();
              }
      
    5. Press Ctrl+F5 to run the code in debug mode.