Software Archive
Read-only legacy content

How to access and manupulate data using wcf service in intel xdk

Selby_R_
Beginner
316 Views

I have created a WCF appication that have access to an sql database. Some codes of the WCF are as below:

Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.ServiceModel
Imports System.Runtime.Serialization
Imports System.Security.Cryptography
 

' NOTE: You can use the "Rename" command on the context menu to change  the class name "Service1" in code, svc and config file together.
' NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.vb at the Solution Explorer and start debugging.
Public Class Service1
Inherits System.Web.UI.Page
Implements IService1
 

 
<ServiceContract()>
Public Interface IService1
    <OperationContract()>
    Function [GetUser]() As UserData
 
    <OperationContract()>
    Sub Insert(Username As String, Password As String, Email As String, Cell As String, DateCreated As Date, LastLogin As Date, Lat1 As String, Lat2 As String, Lat3 As String, Lon1 As String, Lon2 As String, Lon3 As String, Loc1Date As Date, Loc2Date As Date, Loc3Date As Date, Ip1 As String, Ip2 As String, Ip3 As String, IMEI1 As String, IMEI2 As String, IMEI3 As String)
 
    <OperationContract()>
    Sub Update(UserId As Integer, Username As String, Password As String, Email As String, Cell As String, DateCreated As Date, LastLogin As Date, Lat1 As String, Lat2 As String, Lat3 As String, Lon1 As String, Lon2 As String, Lon3 As String, Loc1Date As Date, Loc2Date As Date, Loc3Date As Date, Ip1 As String, Ip2 As String, Ip3 As String, IMEI1 As String, IMEI2 As String, IMEI3 As String)
 
    <OperationContract()>
    Sub SelectUser(UserId As Integer, Username As String, Password As String, Email As String, Cell As String, DateCreated As Date, LastLogin As Date, Lat1 As String, Lat2 As String, Lat3 As String, Lon1 As String, Lon2 As String, Lon3 As String, Loc1Date As Date, Loc2Date As Date, Loc3Date As Date, Ip1 As String, Ip2 As String, Ip3 As String, IMEI1 As String, IMEI2 As String, IMEI3 As String)
 
    <OperationContract()>
    Sub UserLogin(Username As String, Password As String)
 
    <OperationContract()>
    Sub Delete(UserId As Integer)
End Interface
 
<DataContract()>
Public Class UserData
    Public Sub New()
        Me.UserTable = New DataTable("Users")
    End Sub
 
    <DataMember()>
    Public Property UserTable() As DataTable
End Class
 

Public Function [GetUser]() As UserData Implements IService1.GetUser
    Dim constr As String = ConfigurationManager.ConnectionStrings("nighstanddata").ConnectionString
    Using con As New SqlConnection(constr)
        Using cmd As New SqlCommand("SELECT UserId, Username, Password, Email, Cell, DateCreated, LastLogin, Lat1, Lat2, Lat3, Lon1, Lon2, Lon3, Loc1Date, Loc2Date, Loc3Date, Ip1, Ip2, Ip3, IMEI1, IMEI2, IMEI3  FROM Users")
            Using sda As New SqlDataAdapter()
                cmd.Connection = con
                sda.SelectCommand = cmd
                Using dt As New DataTable()
                    Dim User As New UserData()
                    sda.Fill(User.UserTable)
                    Return User
                End Using
            End Using
        End Using
    End Using
End Function
Public Sub UserLogin(Username As String, Password As String) Implements IService1.UserLogin
    Dim wrapper As New E3Des("MyMusterISubMIt")
    Dim constr As String = ConfigurationManager.ConnectionStrings("nighstanddata").ConnectionString
    Dim cmd As New SqlCommand()
    Dim con As New SqlConnection(constr)
    cmd.Connection = con
    cmd.CommandText = "Select Username, Password From Users WHERE (Username=@Username AND Password=@Password)"
    cmd.Parameters.AddWithValue("@Username", wrapper.EncryptData(Username))
    cmd.Parameters.AddWithValue("@Password", EncryptMan(Password))
    con.Open()
    Dim rd As Integer = cmd.ExecuteNonQuery()
    If rd <> 1 Then
        ClientScript.RegisterStartupScript(Me.GetType(), "AlertMessageBox", "alert('Wrong login credintials');", True)
    Else
        ClientScript.RegisterStartupScript(Me.GetType(), "AlertMessageBox", "alert('Login Successful');", True)
    End If
    con.Close()
End Sub
' Some Sub and functions omitted
End Class

Web.config file looks like this:

<?xml version="1.0"?>
 
<configuration>
<connectionStrings>
 
<add name="nighstanddata" connectionString="Data Source=localhost\SQLEXPRESS;Initial Catalog=nddata;Integrated Security=True"  />
 
</connectionStrings>
 
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.serviceModel>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
  </behaviors>
  <protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
  </protocolMapping>    
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
  <modules runAllManagedModulesForAllRequests="true"/>
  <!--
    To browse web app root directory during debugging, set the value below to true.
    Set to false before deployment to avoid disclosing web app folder information.
  -->
  <directoryBrowse enabled="true"/>
  </system.webServer>
 
  </configuration>

Now in my Intel XDK App (Application Framework), I have created a web service called MyApi. Two files where created, a javascript file and Json file. This is where my confusion comes. I have no Json Background but I googled and followed some online tutorials, but still I couldn't get this to work. I have used the placeholder code and made few changes several times, without luck.

I want to be able to login and also insert and update database records.

Here is my current .Json file content:

{
"endpoints": [
{
"name": "InsertUser",
"dashboardUrl": "http://localhost:57014/Service1.svc",
"methods": [
  {
    "MethodName": "Insert",
    "Synopsis": "Insert new recors in user"
  },
  {
    "MethodName": "Update",
    "Synopsis": "Updates selected User record",
    "parameters": [
      {
        "Name": "UserId",
        "Required": "Y",
        "Default": "",
        "Type": "number",
        "Description": "UserId  to be updated."
      }
    ]
   },
     {
    "MethodName": "SelectUser",
    "Synopsis": "Selects User record",
    "parameters": [
      {
        "Name": "UserId",
        "Required": "Y",
        "Default": "",
        "Type": "number",
        "Description": "UserId  to be selected."
      }
    ]
   },
   {
    "MethodName": "methodA1Authenticate",
    "Synopsis": "This is a bare-boned implementation of basic OAuth 2 authentication.  We suggest you hook this method up to your login button. Depending on the service, other parameters may be necessary.",
    "parameters": [
      {
        "Name": "response_type",
        "Required": "Y",
        "Default": "code",
        "Type": "string",
        "Description": "code for authentication code, token for implicit"
      },
      {
        "Name": "redirect_uri",
        "Required": "Y",
        "Default": "http://127.0.0.1:58889/Home",
        "Type": "string",
        "Description": "The redirect_uri must match the redirect uri in your app settings on the API website. You must use the localhost/127.0.0.1 url provided for the services tab or else your service won't work, but you are free to use whatever url you want after that."
      }
    ]
   },
   {
    "MethodName": "authenticatedMethodA1",
    "Synopsis": "A function call that requires an access token acquired from first authenticating the service",
    "parameters": [
      {
        "Name": "param_1_name",
        "Required": "Y",
        "Default": "",
        "Type": "string",
        "Description": "Description of the first parameter."
      }
     ]
    }
    ]
    }

My .Js file:

(function (credentials, helpers) {
  var exports = {};
  
  /* Data Feed Function */
  exports.methodA1 = function (params) {
    var url = 'http://localhost:57014/Service1.svc';
    return $.ajax({url: url});
  };
  
  exports.methodA1User = function(params) {
    var url = 'http://localhost:57014/Service1.svc/GetUser/' + params.UserId;
    delete params.UserId;
    if (params) url = url + '?' + $.param(params);
    return $.ajax({url: url, type: 'GET'});
  };
  
  /* OAuth Functions */
  exports.methodA1Authenticate = function(params) {
    // var implicitUrl = 'https://www.exampleurl.com/auth?';
    var url = {
      codeUrl: 'http://localhost:57014/Service1.svc/UserLogin?',
      tokenUrl: 'http://localhost:57014/access_token?'
    };
    
    //parameters will vary from service to service
    /* var = implicitParams {
      client_id: credentials.apiKey,
      redirect_uri: params.redirect_uri,
      response_type: params.response_type
    } */
    var urlParams = {
      code: {
        client_id: credentials.apiKey,
        redirect_uri: params.redirect_uri,
        response_type: params.response_type
      },
      token: {
        client_secret: credentials.apiSecret,
        grant_type: 'authorization_code'
      }
    };
    
    //helper oauth functions return access token. check to see if service uses authentication code or implicit oauth
    //return helpers.oauth2Implicit(implicitUrl, implicitParams)
    return helpers.oauth2AuthCode(url, urlParams)
    .then(function(token){
      var db = window.localStorage;
      //'service_access_token' should be unique to each service so that multiple authenticated services can be used
      db.setItem('service_access_token', token);
      return token;
    })
    .fail(function(err){
      console.log(err);
    });
  };
  
  exports.authenticatedMethodA1 = function(params){
    var token = window.localStorage.getItem('service_access_token')
    if (!token) return 'Need access token before making call';
    
    var urlParams = $.extend({access_token: token}, params);
    var completeUrl = 'http://localhost:57014/Service1.svc/UserLogin?' +  $.param(urlParams);
    return $.ajax({
      url: completeUrl,
      type: 'GET',
      dataType: 'json'})
    .then(function(response){
      return response;
    })
    .fail(function(err){
      return err.responseText;
    });
  };
  
  return exports;
})

 

0 Kudos
2 Replies
Brian_W_Intel
Employee
316 Views

Hey Selby,

I'm not sure how much I can help you with your question directly, but I have a few questions and insights that might help us get a little closer.

You've instantiated functions Insert, Update, and SelectUser inside your .json file that you haven't added to your .js file. So if you're trying to access any of those you won't be able to, since they're currently undefined. Right now, the only functions you would have access to within the XDK are methodA1Authenticate and authenticatedMethodA1.

Here's where I get a little fuzzy, as I don't have any .NET experience. I'm not sure what luck you'll have trying to use the built in OAuth functions, since they're used to access RESTful APIs with OAuth 2.0 like Dropbox, Instagram, etc. It was meant to be a general purpose solution for those types of services, but I'm unsure if it can handle a WCF REST service the same way it handles the other ones. Usually the parameters passed to these are all the same or very similar, but I'm not sure what it is your login (I assume this is your authentication equivalent) call is looking for, but if it's anything other than what other OAuth2 calls are looking for, you'll have to write your own js function inside your .js file that makes the call. You'll have to add them to exports (i.e. exports.loginFunction = function(params){}), but then so long as you add a loginFunction to your .json file you should be able to call it within the XDK.

Maybe someone with more .NET and WCF experience can comment further, but my assumption is the boilerplate code won't accomplish what you want it to.

Brian

0 Kudos
Jamal_A_
Beginner
316 Views

Selby,

I suggest you start with a simple Hello World WCF service and see if the $.ajax( ) call returns with a success.

BTW, you may need to add the following to the web.config (if you get an error in IIS)
<validation validateIntegratedModeConfiguration="false" />

Also, in Visual Studio you may need the following to be added to the Markup of the IService1.svc. Update the YourNamespace.UserService to proper reference:

<%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.UserService"
                Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

Jamal

 

0 Kudos
Reply