Skip to Content

Afaria API 203 - Build Your Own Self Service Portal - View User Device Information & Inventory

Introduction

This is the third in a series of documents on creating your own Enrollment Portal or End-User Self-Service portal. The focus of this document is on retrieving device info and inventory information using the API.  It is meant as a continuation of our previous efforts in Afaria API 101, Afaria API 201 and Afaria API 202 and assumes completion of those sections. Best coding practices are not necessarily followed to allow for clarity in the instruction of use of the Afaria API. Care must be taken to check for nulls and incorrect values when interacting with these APIs.

Requirements & Assumptions

Table of Contents

Prep-Work

This section will primarily cover the UI changes which are necessary for interacting with the new feature. You may skip to the Retrieving Device Info section if you wish to learn more about the API calls for GetDeviceInfo and GetDeviceProperties.

  1. First, open the project as edited in Afaria API 202 or created in Afaria API 201.
  2. If using the project from Afaria API 201, please create the UI elements mentioned in steps 2 and 3 of Afaria API 202.
  3. At the top of the form, add two new buttons as follows
    1. Name the first ButtonTabEnroll, set the text to "New Device" and add a CommandArgument equal to 0.
    2. Name the second ButtonTabDevices, set the text to "My Devices" and add a CommandArgument equal to 1.
    3. In the Design view, double-click on both buttons to create the stub functions for the Clicked event.
  4. Add a MultiView and View around the previously existing items, including their div tags.
    1. Leave the controls LabelUserName, TextBoxUserName and LabelUserWarning outside of the MultiView so that they may be reused.
    2. Give the MultiView a name of MultiViewMain
    3. Give the View a name of ViewEnroll
  5. Add a second View below ViewEnroll and name it ViewDevices. This will be where we will add items for Afaria API 203's lesson. In this view:
    1. Add a button called ButtonGetDevices, with text of your choosing which will be used to refresh the user's device list.
    2. In the Design view, double-click the new button to create the stub function for the Clicked event.
  6. Add a new function named setTabViewState which takes a button as an argument and returns void.
    1. Add an integer named selectedTabIndex, with a default value of 0.
    2. Parse the argument's CommandArgument into selectedTabIndex.
    3. Enable both Buttons by name.
    4. Disable the Button passed as an argument.
    5. Set MultiViewMain's ActiveViewIndex equal to the selectedTabIndex.
  7. Add references to setTabViewState in the Click event functions created in step 3-3 and pass the sender cast as a Button.
  8. Create a function named getPortalSetup, which takes no parameters and returns nothing.
    1. Move the previously existing functionality from Page_Load into this function.
    2. Below the code that retrieves the Portal's enrollment code dictionary, save the dictionary to the ViewState. We do this since the button presses will cause the a postback. There are other more efficient ways of doing this, but for simplicity's sake, we'll use the ViewState.
  9. In Page_Load:
    1. Set the enrollment code dictionary to the dictionary in the ViewState defined in 8-2.
    2. Check if the enrollment code dictionary is null, and if it is:
      1. Set MultiViewMain's ActiveViewIndex to 0, which will make the enroll view to be the default for the initial page load.
      2. Set ButtonTabEnroll's Enabled property to false to indicate the selected page.
      3. Call getPortalSetup.
  10. Create a new function named getDeviceList, which takes no parameters and returns nothing.
    1. Add a call to the new function, getDeviceList, in ButtonGetDevices_Click and ButtonTabDevices_Click.

Retrieving Device Info

  1. Add a new service reference to the Devices Service, following the instructions given in Afaria API 101, and call it AfariaDevices. We won't add an using statement to the project to keep from creating ambiguous references between AfariaDevices and AfariaPolicy.
  2. Add a property to AfariaHelper for the DevicesServiceClient and name it svcDevices.
  3. Add a method to AfariaHelper named initDevicesService, which performs the same function as initPolicyService and initServerPropertiesService, but for the Devices service.

    protected void initDevicesService()

    {

        svcDevices = new AfariaDevices.DevicesServiceClient("NetTcpBinding_IDevicesService"

                                            , "net.tcp://" + APIaddress + ":7982/AfariaService/Devices");

        svcDevices.ClientCredentials.Windows.ClientCredential.Domain = APIdomain;

        svcDevices.ClientCredentials.Windows.ClientCredential.UserName = APIaccount;

        svcDevices.ClientCredentials.Windows.ClientCredential.Password = APIpassword;

        AfariaDevices.ContextInfo ci = svcDevices.InitContext(contextID);

        if(ci.TenantId == -1)

        {

              svcDevices.SetTenantIdContext(tenantID);

        }

        contextCount++;

    }

  4. Add a method to AfariaHelper named isDevicesServiceOperable, which returns a boolean and performs the same function as isPolicyServiceOperable and isServerPropertiesServiceOperable, but for the Devices service.
    1. Since the Devices Service isn't necessarily needed In the isDeviceServiceOperable method, add code which will call initDevicesService if svcDevices is null.

      protected bool isDevicesServiceOperable()

      {

          bool ret = false;

          if(svcDevices != null)

          {

                if(svcDevices.State == System.ServiceModel.CommunicationState.Faulted)

                {

                    svcDevices.Abort();

                    contextCleanup();

                    svcDevices = null;

                    try

                    {

                          initDevicesService();

                          ret = true;

                    }

                    catch(Exception ex)

                    {

                          throw new Exception("Error initializing service in isDevicesServiceOperable.", ex);

                    }

                }

                else if(svcDevices.State == System.ServiceModel.CommunicationState.Opened)

                {

                    ret = true;

                }

          }

          else

          {

                try

                {

                    initDevicesService();

                    ret = true;

                }

                catch (Exception ex)

                {

                    throw new Exception("Error initializing service in isDevicesServiceOperable.", ex);

                }

          }

          return ret;

      }

  5. Add a public method to AfariaHelper named getDeviceInfo which takes a string as a parameter and returns a DataTable.
    1. Check if the string parameter is null/empty since there is no need to query the API if there is no value.
    2. Check if the Devices service is open by calling IsDevicesServiceOperable. If it returns false, just return. Otherwise, do the following.
    3. Call svcDevices.GetFirstIds with the following parameters and save the results to a string array:
      1. 0, which will cause the API to return the results starting with the first device.
      2. Some integer (eg 20) which means there will be a maximum of 20 rows returned. To return all potential results, specify -1. This could be a bad idea however in the case that a search value is specified which would return many results. Since most portal users will be authenticated and not able to specify this value, this may not be a concern in your environment.

        string[] deviceIDs = svcDevices.GetFirstIds(0, 20

                      , AfariaDevices.SupportedClients.Android

                            & AfariaDevices.SupportedClients.Ios

                            & AfariaDevices.SupportedClients.WinPhone

                      , AfariaDevices.SearchFields.SelfServiceUserName

                      , id, out ds);

    4. Check to make sure that at least one Device ID is returned; exit if not.
    5. Call svcDevices.GetDeviceInfo with the following parameters and save the results to a DeviceInfo array:
      1. DeviceInfoDataRetrievalTypes.All in order to pull back info for different device types.
      2. The array of device IDs returned in step 3.

        AfariaDevices.DeviceInfo[] devInfos;

        devInfos = svcDevices.GetDeviceInfo(AfariaDevices.DeviceInfoDataRetrievalTypes.All, deviceIDs);

        foreach(AfariaDevices.DeviceInfo info in devInfos)

        {

        ...

    6. Set up the DataTable and add columns for any data which you may wish to display, along with a client ID, such as ClientGUID and/or ClientUID.
    7. Loop through the returned DeviceInfos and add the desired data to the DataTable which will be returned.
      1. Most information necessary will be available as immediate properties of the DeviceInfo object, but some data will require deeper inspection.
      2. For devices of ClientType.Ios (compare to DeviceInfo.ClientType), the DeviceInfo.IosDeviceInfo property contains the IMEI, SerialNumber, UDID and a few other non-generalizable types.
      3. For devices of ClientType.WinPhone, the DeviceInfo.WinPhoneDeviceInfo property contains the IMEI, Manufacturer, Model and a few other non-generalizable types.
      4. Other device types have some valuable information in the DeviceInfo.DeviceIdInfo property. This is where the name displayed in the Afaria Administrator is available, as the Value property.
      5. Some info that may be desired, such as phone number, is not available via the GetDeviceInfo call, so it is necessary to create another function to call GetDeviceProperties. Put a place-holder under each type, so that it is quickly replaceable with a call to the function that will be created in the next step.

        object[] tmp = new object[] { info.ClientUid //0-identifier

                            , info.ClientGuid //1-identifier

                            , info.DeviceIdInfo.Value.Trim() //2-display name

                            , info.ClientType.ToString() //3-device type

                            , info.PlatformVersion //4-os version

                            , info.CorporateOwned //5-corporate

                            , info.DeviceComplianceStatus //6-compliant

                            , string.Empty //7-imei

                            , string.Empty //8-serial #

                            , string.Empty //9-phone number

                            , string.Empty //10-Manufacturer Model

                            , string.Empty //11-OS ID (UDID/AndroidID/MobileID)

                            , info.ConnectionInfo.LastConnection //12-last connection

                            };

        switch(info.ClientType)

        {

            case AfariaDevices.ClientType.Ios:

                  tmp[7] = info.IosDeviceInfo.Imei;

                  tmp[8] = info.IosDeviceInfo.SerialNumber;

                  tmp[11] = info.IosDeviceInfo.Udid;

                  //place-holder for GetDeviceProperties

                  break;

        ...

  6. Add a protected method to AfariaHelper named getDeviceProps, which takes parameters of ClientType and a string for device ID, and returns a Dictionary<string, string>. This method will call GetDeviceProperties. GetDeviceProperties takes a complex request, with multiple clients and client types, with different classes per client type, and properties per class type. The easiest way to determine which properties (and expected values) are available is by inspecting the "Hardware Inventory" for existing devices. The classes that are available are in the left selection box, with the properties being the first column in the right detail info box (see the picture below for illustration).

    These values can also be returned by calling GetDeviceProperties and specifying true for the request property named ReturnSchemaClassPropertyDefinitions.
    *Note: This call can return a significant amount of data, so it is common to have to adjust the sizes of buffers, as covered in Afaria API 101.
    1. GetDeviceProperties takes ClientUID as an int for the specifier for the client, but the ClientUID returned by GetDeviceInfo is a string. This is due to the fact that Afaria 7.0 SP4 and prior, the primary records for iOS devices was in a separate table than other device types, and the ClientUID could be duplicated. iOS devices will have the string "Ios" prepended to the ClientUID. Try to parse the passed ClientUID, and if that fails, try to parse the ClientUID without the first three characters.
    2. Check if the Devices service is available by calling isDevicesServiceOperable, and make sure that you could parse the ClientUID in step 6.1.
    3. If the check in 6.2 succeeds, it will be possible to set up the DevicePropertiesRequest.
      1. Create a DevicePropertiesRequest object, named as request, and initialize it. A DevicePropertiesRequest is a complex object, so we will need to initialize several properties.
      2. Initialize request.DBIds as a new DevicePropertiesId array, with a length of 1. It is possible to request information for more than one device at a time, but for simplicity's sake, this method will only handle one device.
        1. Initialize request.DBIds[0] as a DevicePropertiesId.
        2. Set request.DBIds[0].ClientType to the ClientType parameter.
        3. Set request.DBIds[0].DBId to the ClientUID which was parsed in step 6.1.
      3. Initialize request.RequestParameters as a DevicePropertiesRequestParameter array with a length of 1.
        1. Initialize request.RequestParameters[0] as a DevicePropertiesRequestParameter.
        2. Set request.RequestParameters[0].ClientType to the ClientType parameter.
      4. Add a switch based on the ClientType parameter, as different information will need to be requested by ClientType. This is necessary since the properties requested for each ClientType may differ, and may be named differently by ClientType.
        1. For each ClientType, the request.RequestParameters[0].ClassPropertiesList array must be initialized, and each ClassPropertiesList item must be initialized.
        2. For each ClassPropertiesList in the array, do the following. Multiple ClassNames can be specified per ClassPropertiesList, and multiple PropertyNames per ClassName.
          1. The value must be set for ClassName (e.g. request.RequestParameters[0].ClassPropertiesList[0].ClassName = "Device";).
          2. The PropertyNames property, a string array, must be initialized/set (e.g. request.RequestParameters[0].ClassPropertiesList[0].PropertyNames[1] = "Serial number";)
      5. AfariaDevices.DevicePropertiesRequest request = new AfariaDevices.DevicePropertiesRequest();

        request.DBIds = new AfariaDevices.DevicePropertiesId[1];

        request.DBIds[0] = new AfariaDevices.DevicePropertiesId();

        request.DBIds[0].ClientType = deviceType;

        request.DBIds[0].DBId = deviceDBId;

        request.RequestParameters = new AfariaDevices.DevicePropertiesRequestParameter[1];

        request.RequestParameters[0] = new AfariaDevices.DevicePropertiesRequestParameter();

        request.RequestParameters[0].ClientType = deviceType;

        request.ReturnSchemaClassPropertyDefinitions = false;

        switch (deviceType)

        {

            case AfariaDevices.ClientType.Ios:

                  request.RequestParameters[0].ClassPropertiesList = new AfariaDevices.DevicePropertiesRequestClassProperty[2];

                  request.RequestParameters[0].ClassPropertiesList[0] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                  request.RequestParameters[0].ClassPropertiesList[0].ClassName = "Device";

                  request.RequestParameters[0].ClassPropertiesList[0].PropertyNames = new string[1];

                  request.RequestParameters[0].ClassPropertiesList[0].PropertyNames[0] = "Model";

                  request.RequestParameters[0].ClassPropertiesList[1] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                  request.RequestParameters[0].ClassPropertiesList[1].ClassName = "Phone";

                  request.RequestParameters[0].ClassPropertiesList[1].PropertyNames = new string[1];

                  request.RequestParameters[0].ClassPropertiesList[1].PropertyNames[0] = "Phone number";

                  break;

        ...

    4. The DevicePropertiesRequest object should be fully built, call Devices.GetDeviceProperties, passing the DevicePropertiesRequest as the sole parameter, and save the results to a DataSetSurrogate object.

      AfariaDevices.DataSetSurrogate dss = svcDevices.GetDeviceProperties(request);

    5. If the call to DevicePropertiesRequest was made inside of the ClientType switch, assure that the appropriate information is returned for the device type, and add the information to the Dictionary to return.
      • The DataSetSurrogate, which contains the  is a serializable version of the DataSet which is standard with .NET. It is a somewhat complex object type, the full description/explanation of which, is beyond the scope of this document.
      • The DataSetSurrogate contains an array of DataTableSurrogates, which will correlate to the Classes that were requested in step 6.3.4.2.1.
      • The DataTableSurrogate contains an array of DataColumnSurrogates and an two dimensional array which contains the requested data.
      • The DataColumnSurrogate type contains the column name in the _columnName property, and the data type is described in the _dataType property, with the type described in the _dataType.m_sType string.

        case AfariaDevices.ClientType.Ios:

            if ((dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName == "Model")

                  && (dss._dataTableSurrogates[1]._dataColumnSurrogates[0]._columnName == "Phone number")

                  && dss._dataTableSurrogates[0]._records != null

                  && dss._dataTableSurrogates[1]._records != null)

            {

                  deviceProps.Add(dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName

                      , dss._dataTableSurrogates[0]._records[0][0].ToString()); //Model

                  deviceProps.Add(dss._dataTableSurrogates[1]._dataColumnSurrogates[0]._columnName

                      , dss._dataTableSurrogates[1]._records[0][0].ToString()); //Phone number

            }

            break;

  7. In getDeviceInfo, replace the place-holders from step 5.7.5 with calls to getDeviceProps and save the returned data to a dictionary which will be used to return the rest of the information for the UI elements.

    additionalProps = getDeviceProps(info.ClientType, info.ClientUid);

    if (additionalProps != null)

    {

        if (additionalProps.ContainsKey("Model"))

        {

              tmp[10] = additionalProps["Model"];//Model

        }

        if (additionalProps.ContainsKey("Phone number"))

        {

              tmp[9] = additionalProps["Phone number"];//PhoneNo

        }

    }

    1. Set the necessary items in the DataTable to be returned, using the Dictionary items from step 7.
    2. Return the DataTable.
  8. No further changes that interact with the API are necessary, in the next section, we'll tie these changes into the UI interaction.

Wrapping Up

    1. In the Design view of Index.aspx, add a GridView and name it GridViewDeviceSelector (in preparation for the next document in this series which will cover performing device actions).
    2. GridViewDeviceSelector will have an greater than symbol when selected, click on this, then Auto Format... on the menu that pops up. Select a theme for the box which appeals to you, and helps differentiate between records. We will use Professional.
    3. In the popup menu for GridViewDeviceSelector, make sure that Auto-generate fields is selected and that there is a Select field in Selected fields. This will cause the columns/headers to be populated with all data from the DataTable that we will manually bind as a data source, and give us select buttons for the next document in this series.

    4. Back in Index.aspx.cs:
      1. Check if the username is populated in TextBoxUserName, and exit or set a warning in LabelUserWarning.
      2. Otherwise, create an instance of AfariaHelper as was done in getPortalSetup.
      3. Call apiHelper.getDeviceInfo using the username that was in TextBoxUserName and save the results to a DataTable.
      4. Set GridViewDeviceSelector.DataSource to the DataTable returned in the step above.
      5. Call GridViewDeviceSelector.DataBind to bind the DataTable to the GridView and display to the user.

private void getDeviceList()

{

    if (!string.IsNullOrWhiteSpace(TextBoxUserName.Text))

    {

          System.Data.DataTable dt;

          using (AfariaHelper apiHelper = new AfariaHelper(getConfigSetting("AfariaAPIServiceAccountDomain")

                        , getConfigSetting("AfariaAPIServiceAccountUsername")

                        , getConfigSetting("AfariaAPIServiceAccountPassword")

                        , getConfigSetting("AfariaAPIServiceAddress")))

          {

              dt = apiHelper.getDeviceInfo(TextBoxUserName.Text);

          }

          GridViewDeviceSelector.DataSource = dt;

          GridViewDeviceSelector.DataBind();

    }

    else

    {

          LabelUserWarning.Text = "A username must be specified to retrieve info.";

    }

}

Full Example Program

  • Index.aspx.cs

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Web;

    using System.Web.UI;

    using System.Web.UI.WebControls;

    using AfariaAPI201.AfariaPolicy;

    using AfariaAPI201;

    namespace AfariaAPI201

    {

        public partial class index : System.Web.UI.Page

        {

            Dictionary<string, string> m_codeDict;

            protected void Page_Load(object sender, EventArgs e)

            {

                m_codeDict = (Dictionary<string,string>)ViewState["codeDict"];

                if(m_codeDict == null)//first page load

                {

                    MultiViewMain.ActiveViewIndex = 0;

                    ButtonTabEnroll.Enabled = false;

                    getPortalSetup();

                }

            }

            protected void ButtonGetCode_Click(object sender, EventArgs e)

            {

                resetUI();

                try

                {

                    using (AfariaHelper apiHelper = new AfariaHelper(getConfigSetting("AfariaAPIServiceAccountDomain")

                                                                    , getConfigSetting("AfariaAPIServiceAccountUsername")

                                                                    , getConfigSetting("AfariaAPIServiceAccountPassword")

                                                                    , getConfigSetting("AfariaAPIServiceAddress")))

                    {

                        switch(DropDownListClientType.SelectedValue)

                        {

                            case "Ios":

                                setHyperlinkEnrollmentLink(apiHelper.getEnrollmentUrl(TextBoxUserName.Text,

                                    m_codeDict["Ios"],

                                    TextBoxEmailAddress.Text));

                                LabelUserInstructions.Text = "Click on the below URL and follow the prompts to enroll.";

                                break;

                            case "Android":

                                setHyperlinkEnrollmentLink(apiHelper.getEnrollmentUrl(TextBoxUserName.Text,

                                    m_codeDict["Android"],

                                    TextBoxEmailAddress.Text,

                                    ClientType.Android));

                                LabelUserInstructions.Text = "Download the Afaria client from the Google Play store, and return to this page and click on the below link.";

                                break;

                            case "WinPhone":

                                setHyperlinkEnrollmentLink(apiHelper.getEnrollmentUrl(TextBoxUserName.Text,

                                    m_codeDict["WinPhone"],

                                    TextBoxEmailAddress.Text,

                                    ClientType.WinPhone));

                                LabelUserInstructions.Text = "Copy the Enrollment Code URL below to enter it into the Server address field on Company Apps of your device.";

                                LabelUserInstructions.Enabled = true;

                                break;

                            case "WinMobileProfessional":

                                LabelUserInstructions.Text = "Copy the Enrollment Code following to enter it into the client on your device for enrollment:";

                                LabelUserInstructions.Text += "\r\n\r\n" + m_codeDict["WinMobileProfessional"];

                                LabelUserInstructions.Enabled = true;

                                break;

                            case "WinMobileStandard":

                                LabelUserInstructions.Text = "Copy the Enrollment Code following to enter it into the client on your device for enrollment:";

                                LabelUserInstructions.Text += "\r\n\r\n" + m_codeDict["WinMobileStandard"];

                                LabelUserInstructions.Enabled = true;

                                break;

                            case "Win32":

                            case "BlackBerry":

                            default:

                                LabelUserWarning.Text += "\r\nUnsupported Client Type.";

                                break;

                        }

                    }

                }

                catch (Exception ex)

                {

                    System.Diagnostics.Trace.WriteLine(ex.Message);

                    System.Diagnostics.Trace.WriteLine(ex.StackTrace);

                    LabelUserWarning.Text += "\r\nAn error occurred while processing, please try again and notify Support if this message persists.";

                }

            }

            private void setHyperlinkEnrollmentLink(string url)

            {

                HyperLinkEnrollmentLink.NavigateUrl = url;

                HyperLinkEnrollmentLink.Text = url;

                HyperLinkEnrollmentLink.Enabled = true;

                HyperLinkEnrollmentLink.Visible = true;

            }

            private string getConfigSetting(string setting)

            {

                string value = string.Empty;

                if (System.Configuration.ConfigurationManager.AppSettings.Count > 0)

                {

                    value = System.Configuration.ConfigurationManager.AppSettings[setting];

                }

                return value;

            }

            private void getPortalSetup()

            {

                using (AfariaHelper apiHelper = new AfariaHelper(getConfigSetting("AfariaAPIServiceAccountDomain")

                                        , getConfigSetting("AfariaAPIServiceAccountUsername")

                                        , getConfigSetting("AfariaAPIServiceAccountPassword")

                                        , getConfigSetting("AfariaAPIServiceAddress")))

                {

                    string sspGUID = getConfigSetting("AfariaSSPGUID");

                    if (string.IsNullOrWhiteSpace(sspGUID))

                    {

                        string sspName = getConfigSetting("AfariaSSPName");

                        if (string.IsNullOrWhiteSpace(sspName))

                        {

                            sspName = "NewCustomPortal";

                            setConfigSetting("AfariaSSPName", sspName);

                        }

                        sspGUID = apiHelper.getNewPortalGUID(sspName);

                        setConfigSetting("AfariaSSPGUID", sspGUID);

                        resetUI();

                        ButtonGetCode.Enabled = false;

                        LabelUserWarning.Text = "Portal not configured. Please contact support. REF:SSP=[" + sspName + "]";

                    }

                    else

                    {

                        m_codeDict = apiHelper.getPortalCodes(sspGUID);

                        ViewState["codeDict"] = m_codeDict;

                    }

                }

            }

            private void getDeviceList()

            {

                if (!string.IsNullOrWhiteSpace(TextBoxUserName.Text))

                {

                    System.Data.DataTable dt;

                    using (AfariaHelper apiHelper = new AfariaHelper(getConfigSetting("AfariaAPIServiceAccountDomain")

                                , getConfigSetting("AfariaAPIServiceAccountUsername")

                                , getConfigSetting("AfariaAPIServiceAccountPassword")

                                , getConfigSetting("AfariaAPIServiceAddress")))

                    {

                        dt = apiHelper.getDeviceInfo(TextBoxUserName.Text);

                    }

                    GridViewDeviceSelector.DataSource = dt;

                    GridViewDeviceSelector.DataBind();

                }

                else

                {

                    LabelUserWarning.Text = "A username must be specified to retrieve info.";

                }

            }

            private void setConfigSetting(string key, string value)

            {

                System.Configuration.Configuration config = null;

                try

                {

                    config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");

                    config.AppSettings.Settings[key].Value = value;

                    config.Save();

                }

                catch (NullReferenceException)

                {

                    //add key, it doesn't exist

                    if(config != null)

                    {

                        config.AppSettings.Settings.Add(key, value);

                        config.Save();

                    }

                }

                catch(Exception ex)

                {

                    System.Diagnostics.Debug.WriteLine("Exception Message: " + ex.Message + "\r\nException Stack: " + ex.StackTrace);

                    throw ex;

                }

            }

            private void resetUI()

            {

                LabelUserWarning.Text = string.Empty;

                HyperLinkEnrollmentLink.Text = string.Empty;

                HyperLinkEnrollmentLink.NavigateUrl = string.Empty;

                HyperLinkEnrollmentLink.Enabled = false;

                HyperLinkEnrollmentLink.Visible = false;

                LabelUserInstructions.Text = string.Empty;

                LabelUserInstructions.Enabled = false;

            }

            protected void ButtonTabEnroll_Click(object sender, EventArgs e)

            {

                setTabViewState((Button)sender);

            }

            protected void ButtonTabDevices_Click(object sender, EventArgs e)

            {

                setTabViewState((Button)sender);

                getDeviceList();

            }

            private void setTabViewState(Button sender)

            {

                int selectedTabIndex = 0;

                int.TryParse(sender.CommandArgument, out selectedTabIndex);

                ButtonTabEnroll.Enabled = true;

                ButtonTabDevices.Enabled = true;

                sender.Enabled = false;

                MultiViewMain.ActiveViewIndex = selectedTabIndex;

            }

            protected void ButtonGetDevices_Click(object sender, EventArgs e)

            {

                getDeviceList();

            }

        }

        public class AfariaHelper : IDisposable

        {

            public string contextID { get; private set; }

            int contextCount;

            string APIdomain, APIaccount, APIpassword, APIaddress;

            PolicyServiceClient svcPolicy;

            AfariaServerProperties.ServerPropertiesServiceClient svcServerProperties;

            AfariaDevices.DevicesServiceClient svcDevices;

            bool disposed = false;

            int tenantID;

    #region Static Methods

            public static List<string> getClientTypes()

            {

                List<string> types = new List<string>();

                foreach (string type in Enum.GetNames(typeof(ClientType)))

                {

                    if (type != "All" && type != "Undefined")

                    {

                        types.Add(type);

                    }

                }

                return types;

            }

    #endregion Statics

    #region Public Instance Methods & Constructor/Destructor

            public AfariaHelper(string APIdomain, string APIaccount, string APIpassword, string APIaddress = "127.0.0.1", int TenantID = 0)

            {

                this.APIdomain = APIdomain;

                this.APIaccount = APIaccount;

                this.APIpassword = APIpassword;

                this.APIaddress = APIaddress;

                this.tenantID = TenantID;

                contextID = Guid.NewGuid().ToString();

                contextCount = 0;

                initPolicyService();

                initServerPropertiesService();

            }

            public void Dispose()

            {

                Dispose(true);

            }

            protected void Dispose(bool disposing)

            {

                if (disposed)

                {

                    return;

                }

                if (disposing)

                {

                    contextCleanup();

                    if (svcPolicy != null)

                    {

                        svcPolicy.Close();

                        svcPolicy = null;

                    }

                }

                disposed = true;

            }

            public string getEnrollmentUrl(string userAccount, string enrollCode, string userEmail, ClientType deviceType = ClientType.Ios)

            {

                string url = string.Empty;

                string activationID = string.Empty;

                activationID = getActivationID(userAccount, enrollCode, userEmail, deviceType);

                if (!(string.IsNullOrEmpty(activationID)) && (isPolicyServiceOperable()))

                {

                    activationID = activationID.Replace(" ", string.Empty); //remove spaces from returned activation ID

                    AfariaPolicy.DataState ds = svcPolicy.OpenPolicy(enrollCode);

                    if (deviceType == ClientType.Android)

                    {

                        svcPolicy.SetServerIdContext("3qcj");

                    }

                    EnrollmentPolicySettings plcySettings = svcPolicy.EnrollmentGetPolicySettings(ds);

                    svcPolicy.Release(ds);

                    if (plcySettings != null)

                    {

                        switch (deviceType)

                        {

                            case ClientType.Ios:

                                url = ((EnrollmentPolicySettingsIos)plcySettings).MdmEnrollmentUrl;

                                url = url.Replace(enrollCode, activationID);

                                break;

                            case ClientType.Android:

                                url = "afaria://e=" + activationID;

                                break;

                            case ClientType.WinPhone:

                                url = ((EnrollmentPolicySettingsWinPhone)plcySettings).MdmEnrollmentUrl;

                                url = url.Replace(enrollCode, activationID);

                                break;

                            default:

                                return string.Empty; //not supported at this time

                        }

                    }

                    else

                    {

                        throw new Exception("Specified enrollment code is invalid.");

                    }

                    return url;

                }

                else

                {

                    throw new Exception("Policy Service is not operable");

                }

            }

          public string getActivationID(string userAccount, string enrollCode, string userEmail, ClientType deviceClientType)

            {

                string output = string.Empty;

                if (isPolicyServiceOperable())

                {

                    EnrollmentCodeActivationIdInfo activationID = svcPolicy.EnrollmentCodeGenerateActivationIdWithAddress(userAccount, enrollCode, userEmail, deviceClientType);

                    output = activationID.CompleteActivationId;

                }

                else

                {

                    throw new Exception("Policy Service is not operable");

                }

                return output;

            }

            public string getNewPortalGUID(string portalName)

            {

                string outString = string.Empty;

                if (!string.IsNullOrWhiteSpace(portalName))

                {

                    if (isServerPropertiesServiceOperable())

                    {

                        Guid portalGUID = svcServerProperties.AddSelfServicePortal(portalName);

                        outString = portalGUID.ToString();

                    }

                    else

                    {

                        throw new Exception("ServerProperties Service is not operable.");

                    }

                }

                return outString;

            }

            public Dictionary<string, string> getPortalCodes(string portalGUID)

            {

                Dictionary<string, string> outDict = new Dictionary<string, string>();

                if (!string.IsNullOrWhiteSpace(portalGUID))

                {

                    Guid guid = new Guid();

                    try

                    {

                        guid = new Guid(portalGUID);

                    }

                    catch (FormatException)

                    {

                        throw new Exception("Portal GUID is invalid.");

                    }

                    catch (OverflowException)

                    {

                        throw new Exception("Portal GUID is invalid.");

                    }

                    AfariaServerProperties.SelfServicePortalConfiguration[] sspConfigs;

                    sspConfigs = svcServerProperties.GetSelfServicePortalConfigurations(new Guid[] { guid });

                    if (sspConfigs.Length == 1)

                    {

                        foreach (AfariaServerProperties.SelfServicePortalEnrollmentCodeInfo code in sspConfigs[0].EnrollmentCodes)

                        {

                            outDict.Add(code.ClientType.ToString(), code.EnrollmentCode);

                        }

                    }

                    else

                    {

                        throw new Exception("Portal does not exist for this GUID.");

                    }

                }

                return outDict;

            }

            public System.Data.DataTable getDeviceInfo(string id)

            {

                System.Data.DataTable dt = null;

                if (!string.IsNullOrWhiteSpace(id))

                {

                    if (isDevicesServiceOperable())

                    {

                        AfariaDevices.DataState ds;

                        string[] deviceIDs = svcDevices.GetFirstIds(0, 20

                                    , AfariaDevices.SupportedClients.Android

                                        & AfariaDevices.SupportedClients.Ios

                                        & AfariaDevices.SupportedClients.WinPhone

                                    , AfariaDevices.SearchFields.SelfServiceUserName

                                    , id, out ds);

                        if(deviceIDs.Length > 0)

                        {

                            dt = new System.Data.DataTable("DeviceInfo");

                            dt.Columns.Add("UID");

                            dt.Columns.Add("ClientGUID");

                            dt.Columns.Add("DisplayName");

                            dt.Columns.Add("DeviceType");

                            dt.Columns.Add("OSversion");

                            dt.Columns.Add("Corporate");

                            dt.Columns.Add("Compliant");

                            dt.Columns.Add("IMEI");

                            dt.Columns.Add("SerialNo");

                            dt.Columns.Add("PhoneNo");

                            dt.Columns.Add("Model");

                            dt.Columns.Add("OSID");

                            dt.Columns.Add("LastConnection");

                            AfariaDevices.DeviceInfo[] devInfos;

                            devInfos = svcDevices.GetDeviceInfo(AfariaDevices.DeviceInfoDataRetrievalTypes.All, deviceIDs);

                            foreach(AfariaDevices.DeviceInfo info in devInfos)

                            {

                                object[] tmp = new object[] { info.ClientUid //0-identifier

                                                            , info.ClientGuid //1-identifier

                                                            , info.DeviceIdInfo.Value.Trim() //2-display name

                                                            , info.ClientType.ToString() //3-device type

                                                            , info.PlatformVersion //4-os version

                                                            , info.CorporateOwned //5-corporate

                                                            , info.DeviceComplianceStatus //6-compliant

                                                            , string.Empty //7-imei

                                                            , string.Empty //8-serial #

                                                            , string.Empty //9-phone number

                                                            , string.Empty //10-Manufacturer Model

                                                            , string.Empty //11-OS ID (UDID/AndroidID/MobileID)

                                                            , info.ConnectionInfo.LastConnection //12-last connection

                                                            };

                                Dictionary<string, string> additionalProps;

                                switch(info.ClientType)

                                {

                                    case AfariaDevices.ClientType.Ios:

                                        tmp[7] = info.IosDeviceInfo.Imei;

                                        tmp[8] = info.IosDeviceInfo.SerialNumber;

                                        tmp[11] = info.IosDeviceInfo.Udid;

                                        additionalProps = getDeviceProps(info.ClientType, info.ClientUid);

                                        if (additionalProps != null)

                                        {

                                            if (additionalProps.ContainsKey("Model"))

                                            {

                                                tmp[10] = additionalProps["Model"];//Model

                                            }

                                            if (additionalProps.ContainsKey("Phone number"))

                                            {

                                                tmp[9] = additionalProps["Phone number"];//PhoneNo

                                            }

                                        }

                                        break;

                                    case AfariaDevices.ClientType.WinPhone:

                                        tmp[7] = info.WinPhoneDeviceInfo.Imei;

                                        tmp[10] = info.WinPhoneDeviceInfo.Manufacturer

                                                    + " " + info.WinPhoneDeviceInfo.Model;

                                        additionalProps = getDeviceProps(info.ClientType, info.ClientUid);

                                        if(additionalProps != null)

                                        {

                                            if (additionalProps.ContainsKey("Mobile ID"))

                                            {

                                                tmp[11] = additionalProps["Mobile ID"];//OS ID

                                            }

                                        }

                                        break;

                                    case AfariaDevices.ClientType.Android:

                                        additionalProps = getDeviceProps(info.ClientType, info.ClientUid);

                                        if(additionalProps != null)

                                        {

                                    

                                            if (additionalProps.ContainsKey("IMEI"))

                                            {

                                                tmp[7] = additionalProps["IMEI"];//IMEI

                                            }

                                            if (additionalProps.ContainsKey("Serial number"))

                                            {

                                                tmp[8] = additionalProps["Serial number"];//SerialNo

                                            }

                                            if (additionalProps.ContainsKey("Phone number"))

                                            {

                                                tmp[9] = additionalProps["Phone number"];//PhoneNo

                                            }

                                            if (additionalProps.ContainsKey("Device maker") &&

                                                additionalProps.ContainsKey("Device model"))

                                            {

                                                tmp[10] = additionalProps["Device maker"].ToUpper()

                                                    + " " + additionalProps["Device model"].ToUpper();// Maker + Model

                                            }

                                        }

                                        break;

                                    default:

                                        //nothing to see here, moving along

                                        break;

                                }

                        

                                System.Data.DataRow dr = dt.Rows.Add(tmp);

                            }

                        }

                    }

                }

                return dt;

            }

    #endregion Public Instance Methods & Constructor/Destructor

    #region Protected/Private Instance Methods

            protected void initPolicyService()

            {

                svcPolicy = new PolicyServiceClient("NetTcpBinding_IPolicyService", "net.tcp://" + APIaddress + ":7982/AfariaService/Policy");

                svcPolicy.ClientCredentials.Windows.ClientCredential.Domain = APIdomain;

                svcPolicy.ClientCredentials.Windows.ClientCredential.UserName = APIaccount;

                svcPolicy.ClientCredentials.Windows.ClientCredential.Password = APIpassword;

                ContextInfo ci = svcPolicy.InitContext(contextID);

                svcPolicy.SetTenantIdContext(tenantID);

                contextCount++;

            }

          protected void initServerPropertiesService()

            {

                svcServerProperties = new AfariaServerProperties.ServerPropertiesServiceClient("NetTcpBinding_IServerPropertiesService"

                                                        , "net.tcp://" + APIaddress + ":7982/AfariaService/ServerProperties");

                svcServerProperties.ClientCredentials.Windows.ClientCredential.Domain = APIdomain;

                svcServerProperties.ClientCredentials.Windows.ClientCredential.UserName = APIaccount;

                svcServerProperties.ClientCredentials.Windows.ClientCredential.Password = APIpassword;

                AfariaServerProperties.ContextInfo ci = svcServerProperties.InitContext(contextID);

                if (ci.TenantId == -1) //TenantId not set

                {

                    svcServerProperties.SetTenantIdContext(tenantID);

                }

                contextCount++;

            }

            protected void initDevicesService()

            {

                svcDevices = new AfariaDevices.DevicesServiceClient("NetTcpBinding_IDevicesService"

                                            , "net.tcp://" + APIaddress + ":7982/AfariaService/Devices");

                svcDevices.ClientCredentials.Windows.ClientCredential.Domain = APIdomain;

                svcDevices.ClientCredentials.Windows.ClientCredential.UserName = APIaccount;

                svcDevices.ClientCredentials.Windows.ClientCredential.Password = APIpassword;

                AfariaDevices.ContextInfo ci = svcDevices.InitContext(contextID);

                if(ci.TenantId == -1)

                {

                    svcDevices.SetTenantIdContext(tenantID);

                }

                contextCount++;

            }

            protected bool isPolicyServiceOperable()

            {

                bool ret = false;

                if (svcPolicy != null)

                {

                    if (svcPolicy.State == System.ServiceModel.CommunicationState.Faulted)

                    {

                        svcPolicy.Abort();

                        contextCleanup();

                        svcPolicy = null;

                        try

                        {

                            initPolicyService();

                            ret = true;

                        }

                        catch (Exception ex)

                        {

                            throw new Exception("Error initializing service in isPolicyServiceOperable.", ex);

                        }

                    }

                    else if (svcPolicy.State == System.ServiceModel.CommunicationState.Opened)

                    {

                        ret = true;

                    }

                }

                return ret;

            }

            protected bool isServerPropertiesServiceOperable()

            {

                bool ret = false;

                if (svcServerProperties != null)

                {

                    if (svcServerProperties.State == System.ServiceModel.CommunicationState.Faulted)

                    {

                        svcServerProperties.Abort();

                        contextCleanup();

                        svcServerProperties = null;

                        try

                        {

                            initServerPropertiesService();

                            ret = true;

                        }

                        catch (Exception ex)

                        {

                            throw new Exception("Error initializing service in isServerPropertiesServiceOperable.", ex);

                        }

                    }

                    else if (svcServerProperties.State == System.ServiceModel.CommunicationState.Opened)

                    {

                        ret = true;

                    }

                }

                return ret;

            }

            protected bool isDevicesServiceOperable()

            {

                bool ret = false;

                if(svcDevices != null)

                {

                    if(svcDevices.State == System.ServiceModel.CommunicationState.Faulted)

                    {

                        svcDevices.Abort();

                        contextCleanup();

                        svcDevices = null;

                        try

                        {

                            initDevicesService();

                            ret = true;

                        }

                        catch(Exception ex)

                        {

                            throw new Exception("Error initializing service in isDevicesServiceOperable.", ex);

                        }

                    }

                    else if(svcDevices.State == System.ServiceModel.CommunicationState.Opened)

                    {

                        ret = true;

                    }

                }

                else

                {

                    try

                    {

                        initDevicesService();

                        ret = true;

                    }

                    catch (Exception ex)

                    {

                        throw new Exception("Error initializing service in isDevicesServiceOperable.", ex);

                    }

                }

                return ret;

            }

            protected bool contextCleanup()

            {

                if (contextCount > 1)

                {

                    contextCount--;

                }

                else if (contextCount == 1 || contextCount == 0)

                {

                    PolicyServiceClient svcTemp = new PolicyServiceClient("NetTcpBinding_IPolicyService", "net.tcp://" + APIaddress + ":7982/AfariaService/Policy");

                    svcTemp.ClientCredentials.Windows.ClientCredential.Domain = APIdomain;

                    svcTemp.ClientCredentials.Windows.ClientCredential.UserName = APIaccount;

                    svcTemp.ClientCredentials.Windows.ClientCredential.Password = APIpassword;

                    svcTemp.InitContext(contextID);

                    svcTemp.CloseContext();

                    contextCount = 0;

                    return true;

                }

                else

                {

                    throw new Exception("We've lost track of our contexts!");

                }

                return false;

            }

            protected Dictionary<string,string> getDeviceProps(AfariaDevices.ClientType deviceType, string deviceID)

            {

                Dictionary<string, string> deviceProps = new Dictionary<string, string>();

                int deviceDBId = -1;

                if (!int.TryParse(deviceID, out deviceDBId))

                {

                    int.TryParse(deviceID.Substring(3), out deviceDBId);

                }

                if (isDevicesServiceOperable() && deviceDBId != -1)

                {

                    AfariaDevices.DevicePropertiesRequest request = new AfariaDevices.DevicePropertiesRequest();

                    request.DBIds = new AfariaDevices.DevicePropertiesId[1];

                    request.DBIds[0] = new AfariaDevices.DevicePropertiesId();

                    request.DBIds[0].ClientType = deviceType;

                    request.DBIds[0].DBId = deviceDBId;

                    request.RequestParameters = new AfariaDevices.DevicePropertiesRequestParameter[1];

                    request.RequestParameters[0] = new AfariaDevices.DevicePropertiesRequestParameter();

                    request.RequestParameters[0].ClientType = deviceType;

                    request.ReturnSchemaClassPropertyDefinitions = false;

                    switch (deviceType)

                    {

                        case AfariaDevices.ClientType.Android:

                            request.RequestParameters[0].ClassPropertiesList = new AfariaDevices.DevicePropertiesRequestClassProperty[3];

                            request.RequestParameters[0].ClassPropertiesList[0] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                            request.RequestParameters[0].ClassPropertiesList[0].ClassName = "Device";

                            request.RequestParameters[0].ClassPropertiesList[0].PropertyNames = new string[2];

                            request.RequestParameters[0].ClassPropertiesList[0].PropertyNames[0] = "IMEI";

                            request.RequestParameters[0].ClassPropertiesList[0].PropertyNames[1] = "Serial number";

                            request.RequestParameters[0].ClassPropertiesList[1] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                            request.RequestParameters[0].ClassPropertiesList[1].ClassName = "Phone";

                            request.RequestParameters[0].ClassPropertiesList[1].PropertyNames = new string[1];

                            request.RequestParameters[0].ClassPropertiesList[1].PropertyNames[0] = "Phone number";

                            request.RequestParameters[0].ClassPropertiesList[2] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                            request.RequestParameters[0].ClassPropertiesList[2].ClassName = "Android";

                            request.RequestParameters[0].ClassPropertiesList[2].PropertyNames = new string[2];

                            request.RequestParameters[0].ClassPropertiesList[2].PropertyNames[0] = "Device model";

                            request.RequestParameters[0].ClassPropertiesList[2].PropertyNames[1] = "Device maker";

                            break;

                        case AfariaDevices.ClientType.Ios:

                            request.RequestParameters[0].ClassPropertiesList = new AfariaDevices.DevicePropertiesRequestClassProperty[2];

                            request.RequestParameters[0].ClassPropertiesList[0] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                            request.RequestParameters[0].ClassPropertiesList[0].ClassName = "Device";

                            request.RequestParameters[0].ClassPropertiesList[0].PropertyNames = new string[1];

                            request.RequestParameters[0].ClassPropertiesList[0].PropertyNames[0] = "Model";

                            request.RequestParameters[0].ClassPropertiesList[1] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                            request.RequestParameters[0].ClassPropertiesList[1].ClassName = "Phone";

                            request.RequestParameters[0].ClassPropertiesList[1].PropertyNames = new string[1];

                            request.RequestParameters[0].ClassPropertiesList[1].PropertyNames[0] = "Phone number";

                            break;

                        case AfariaDevices.ClientType.WinPhone:

                            request.RequestParameters[0].ClassPropertiesList = new AfariaDevices.DevicePropertiesRequestClassProperty[1];

                            request.RequestParameters[0].ClassPropertiesList[0] = new AfariaDevices.DevicePropertiesRequestClassProperty();

                            request.RequestParameters[0].ClassPropertiesList[0].ClassName = "Device";

                            request.RequestParameters[0].ClassPropertiesList[0].PropertyNames = new string[1];

                            request.RequestParameters[0].ClassPropertiesList[0].PropertyNames[0] = "Mobile ID";

                            break;

                        default:

                            throw new Exception("getDeviceProps: Unexpected device type!");

                    }

                    AfariaDevices.DataSetSurrogate dss = svcDevices.GetDeviceProperties(request);

                    switch (deviceType)

                    {

                        case AfariaDevices.ClientType.Android:

                            if ((dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName == "IMEI")

                                && (dss._dataTableSurrogates[0]._dataColumnSurrogates[1]._columnName == "Serial number")

                                && (dss._dataTableSurrogates[1]._dataColumnSurrogates[0]._columnName == "Phone number")

                                && (dss._dataTableSurrogates[2]._dataColumnSurrogates[0]._columnName == "Device model")

                                && (dss._dataTableSurrogates[2]._dataColumnSurrogates[1]._columnName == "Device maker")

                                && dss._dataTableSurrogates[0]._records != null

                                && dss._dataTableSurrogates[1]._records != null

                                && dss._dataTableSurrogates[2]._records != null)

                            {

                                deviceProps.Add(dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName

                                    , dss._dataTableSurrogates[0]._records[0][0].ToString()); //IMEI

                                deviceProps.Add(dss._dataTableSurrogates[0]._dataColumnSurrogates[1]._columnName

                                    , dss._dataTableSurrogates[0]._records[1][0].ToString()); //Serial number

                                deviceProps.Add(dss._dataTableSurrogates[1]._dataColumnSurrogates[0]._columnName

                                    , dss._dataTableSurrogates[1]._records[0][0].ToString()); //Phone number

                                deviceProps.Add(dss._dataTableSurrogates[2]._dataColumnSurrogates[0]._columnName

                                    , dss._dataTableSurrogates[2]._records[0][0].ToString()); //Device model

                                deviceProps.Add(dss._dataTableSurrogates[2]._dataColumnSurrogates[1]._columnName

                                    , dss._dataTableSurrogates[2]._records[1][0].ToString()); //Device maker

                            }

                            break;

                        case AfariaDevices.ClientType.Ios:

                            if ((dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName == "Model")

                                && (dss._dataTableSurrogates[1]._dataColumnSurrogates[0]._columnName == "Phone number")

                                && dss._dataTableSurrogates[0]._records != null

                                && dss._dataTableSurrogates[1]._records != null)

                            {

                                deviceProps.Add(dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName

                                    , dss._dataTableSurrogates[0]._records[0][0].ToString()); //Model

                                deviceProps.Add(dss._dataTableSurrogates[1]._dataColumnSurrogates[0]._columnName

                                    , dss._dataTableSurrogates[1]._records[0][0].ToString()); //Phone number

                            }

                            break;

                        case AfariaDevices.ClientType.WinPhone:

                            if (dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName == "Mobile ID"

                                && dss._dataTableSurrogates[0]._records != null)

                            {

                                deviceProps.Add(dss._dataTableSurrogates[0]._dataColumnSurrogates[0]._columnName

                                    , dss._dataTableSurrogates[0]._records[0][0].ToString()); //Mobile ID

                            }

                            break;

                        default:

                            throw new Exception("getDeviceProps: Unexpected returned device type!");

                    }

                }

                return deviceProps;

            }

    #endregion Protected/Private Instance Methods

        }

    }

  • Index.aspx

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="AfariaAPI201.index" %>

    <!DOCTYPE html>

    <html xmlns="http://www.w3.org/1999/xhtml">

    <head runat="server">

        <title>AfariaAPI-SSP</title>

    </head>

        <body>

            <form id="form1" runat="server">

                <div>

                    <p>

                        <asp:Button ID="ButtonTabEnroll" runat="server" Text="New Device" CommandArgument="0" OnClick="ButtonTabEnroll_Click" />

                        <asp:Button ID="ButtonTabDevices" runat="server" Text="My Devices" CommandArgument="1" OnClick="ButtonTabDevices_Click" />

                    </p>

                </div>

                <div>

                    <asp:Label ID="LabelUserName" runat="server" Text="UserName:"></asp:Label>

                    <asp:TextBox ID="TextBoxUserName" runat="server"></asp:TextBox>

                </div>

                <div>

                    <asp:MultiView ID="MultiViewMain" runat="server">

                        <asp:View ID="ViewEnroll" runat="server">

                            <div>

                                <div>

                                    <asp:Label ID="LabelEmailAddress" runat="server" Text="Email Address:"></asp:Label>

                                    <asp:TextBox ID="TextBoxEmailAddress" runat="server"></asp:TextBox>

                                </div>

                                <div>

                                    <asp:Label ID="LabelClientType" runat="server" Text="Device Type:"></asp:Label>

                                    <asp:DropDownList ID="DropDownListClientType" runat="server" DataSourceID="ObjectDataSourceClientType"></asp:DropDownList>

                                    <asp:ObjectDataSource ID="ObjectDataSourceClientType" runat="server" SelectMethod="getClientTypes" TypeName="AfariaAPI201.AfariaHelper"></asp:ObjectDataSource>

                                </div>

                            </div>

                            <div><asp:Button ID="ButtonGetCode" runat="server" Text="Get Code" OnClick="ButtonGetCode_Click" /></div>

                            <div>

                                <asp:Label ID="LabelUserInstructions" runat="server" Text="" Enabled="False"></asp:Label><br />

                                <asp:HyperLink ID="HyperLinkEnrollmentLink" runat="server" Enabled="False" Visible="False">HyperLink</asp:HyperLink>

                            </div>

                        </asp:View>

                        <asp:View ID="ViewDevices" runat="server">

                            <asp:Button ID="ButtonGetDevices" runat="server" Text="Refresh My Devices List" OnClick="ButtonGetDevices_Click" />

                            <asp:GridView ID="GridViewDeviceSelector" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" OnSelectedIndexChanged="GridViewDeviceSelector_SelectedIndexChanged">

                            <AlternatingRowStyle BackColor="White" ForeColor="#284775" />

                            <Columns>

                                <asp:CommandField ButtonType="Button" ShowSelectButton="True" />

                            </Columns>

                            <EditRowStyle BackColor="#999999" />

                            <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />

                            <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />

                            <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />

                            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />

                            <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />

                            <SortedAscendingCellStyle BackColor="#E9E7E2" />

                            <SortedAscendingHeaderStyle BackColor="#506C8C" />

                            <SortedDescendingCellStyle BackColor="#FFFDF8" />

                            <SortedDescendingHeaderStyle BackColor="#6F8DAE" />

                        </asp:GridView>

                        </asp:View>

                    </asp:MultiView>

                </div>

                <div>

                    <br /><br />

                    <asp:Label ID="LabelUserWarning" runat="server" Text="" Font-Bold="True" ForeColor="Red" Enabled="False"></asp:Label>

                </div>

            </form>

        </body>

    </html>

Tags: