API-NG: VB Example

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Simple
    Junior Member
    • Aug 2009
    • 32

    #1

    API-NG: VB Example

    Yesterday i have posted a code snippet which shows how to get a response from the API using Visual C#. Today i have finished the Visual Basic version.

    The project is a WinForm project and we should add in Form1 the following code using the LoadForm or a ButtonClick event:

    Code:
    Dim Response As New ResponseClass()
            Response.EventTypesList()
    The code should give us a list with all event types. My C# example is based on JSON (Rest). Now i will use JSON-RPC.

    Then we add a new class which is called "ResponseClass". As next we should install Newtonsoft.Json and add the following Imports:

    Code:
    Imports System.IO
    Imports System.Net
    Imports System.Text
    Imports Newtonsoft.Json
    Under the ResponseClass we insert the following classes (this not "best practice" - but here usefull):

    Code:
    Public Class JsonRequest
    
        Public Property jsonrpc As String
        Public Property method As String
        Public Property params As Parameter
        Public Property id As Integer
    
    End Class
    
    Public Class Parameter
        Public Property filter As Request_Filter
    End Class
    
    Public Class Ident
        Public Property id As Integer
    End Class
    Public Class Request_Filter
    
    End Class
    We need this code for our JSON string. More soon. Now we fill the Response Class with following snippet:

    Code:
    Public Class ResponseClass
        Inherits WebClient
    
        Public Sub EventTypesList()
    
            Dim token As String = "your token" 
            Dim key As String = "your api key" ' delayed AppKey
            Dim address As String = "https://api.betfair.com/exchange/betting/json-rpc/v1"
    
            ' Step 1: Creating Request Object (Headers)
    
            Dim request As HttpWebRequest = CType(WebRequest.Create(address), HttpWebRequest)
    
            request.Method = "POST"
            request.ContentType = "application/json"
            request.Headers.Add(HttpRequestHeader.AcceptCharset, "UTF-8")
            request.Headers.Add("X-Application", key)
            request.Headers.Add("X-Authentication", token)
    
            ' Step 2: Creating JSON (RPC)
    
            Dim postData As String = Json_Object()
    
            ' Step 3: Adding JSON as Body (?) to Request (Request = Headers + Body)
    
            Dim bytes As Byte() = Encoding.GetEncoding("UTF-8").GetBytes(postData)
            request.ContentLength = bytes.Length
    
            Dim out_stream As Stream = request.GetRequestStream()
            out_stream.Write(bytes, 0, bytes.Length)
    
            ' Step 4: Getting the Response
    
            Dim response As WebResponse = GetWebResponse(request)
    
            ' Step 5: Transfer Response in a String
    
            Dim in_stream As Stream = response.GetResponseStream()
            Dim reader As New StreamReader(in_stream, Encoding.UTF8)
    
            Dim api_response = reader.ReadToEnd()
    
            ' Step 6: Processing Response String
    
            ' ...
        End Sub
    
        Function Json_Object() As String
    
            Dim rpc_Req As New JsonRequest()
            Dim rpc_Params As New Parameter()
            rpc_Params.filter = New Request_Filter()
    
            rpc_Req.jsonrpc = "2.0"
            rpc_Req.method = "SportsAPING/v1.0/listEventTypes"
            rpc_Req.params = rpc_Params
            rpc_Req.id = 1
    
            Return JsonConvert.SerializeObject(rpc_Req)
    
        End Function
    
    End Class
    The ResponseClass consists of our "main" sub (which procces the request and gets the response) and a function which delivers the json string (based on the other class below). You should also add a breakpoint at the start of the ResponseClass because the code is more a prototype and should be only used with the debugger.

    The most difficult part was for me to create the proper JSON string, esp: the "params" part. Eventually i understand this can be done with nested objects. Our main object is the JsonRequest class which provides all four elements for a JSON-RPC request. The "params" element is based on the class "Parameter" to define a filter which is done in a further class (Request Filter). As we need no filter for our request the Request_Filter class is here empty. Only with this construction plan Json.Net can build the correct json string.

    Json.Net docu: http://james.newtonking.com/json/help/index.html

    (Samples/Serializing Json/Serialize an Object)
  • Peter Simple
    Junior Member
    • Aug 2009
    • 32

    #2
    Here is an example to convert the response sent by the API.

    Code:
    Dim list As J_Response = JsonConvert.DeserializeObject(Of J_Response)(api_response)
    J_Response is a class which constructed to mirror the structure of the json string returned by the API. This class has also nested members (Event_Summary and Event_Type). Please note the use of IList to catch the relevant data.


    Public Class J_Response
    Public Property jsonrpc As String
    Public Property result As IList(Of Event_Summary)
    Public Property id As Integer
    End Class

    Public Class Event_Summary
    Public Property eventType As Event_Type
    Public Property marketCount As Integer
    End Class

    Public Class Event_Type
    Public Property id As Integer
    Public Property name As String
    End Class

    Comment

    • Peter Simple
      Junior Member
      • Aug 2009
      • 32

      #3
      When you serialize or serisalize a JSON request or response it could be better to use private classes (instead of public classes). Thesse classes should then placed inside the (public)ResponseClass.

      The advantage is when you write several different "Response Classes" you avoid to use a JSON class which was used for an other Response Class which could lead to trouble.

      When you familiar with all the concepts of the API you should find an efficient way to structure the code so that you can avoid all the repeating lines.

      Comment

      • Peter Simple
        Junior Member
        • Aug 2009
        • 32

        #4
        A last hint:

        When you work with MarketFilters you can define a time range, e.g.

        Code:
        Public Class MarketFilter
        
            Public Property textQuery As String
            Public Property eventTypeIds As Integer()
            Public Property turnInPlayEnabled As Boolean
            Public Property inPlayOnly As Boolean
            Public Property marketCountries As String()
            Public Property marketTypeCodes As String()
            [B]Public Property marketStartTime As TimeRange
        [/B]
        End Class
        When you define the call "TimeRange" you can run into a problem because it needs to Properties: "from" and "to" but "to" is a key word in VB, so you have to use brackets. Otherwise the reguest ignores the end time. The correct way looks so:

        Public Class TimeRange
        Public Property from As Date
        Public Property [to] As Date
        End Class

        Comment

        • mizar1
          Junior Member
          • Dec 2009
          • 12

          #5
          hello excuse how I can insert a parameter

          example
          "eventTypeIds = 1"?

          Comment

          • Peter Simple
            Junior Member
            • Aug 2009
            • 32

            #6
            This is a snippet from my actual code. The Function JsonData delivers the json string which passed to the API. Tu use eventTypeIds you have to deliver the EventType IDs as string array lime eventTypeIds = {"1"} or eventTypeIDs = {"1", "7"}.

            (When a Function/Method/field is private i do not write "Private" which may be not "standart" but this is is my personal code. And one of my other "quirks" is that i use often "Bytes" instead of Integer of Long for small numbers.)

            Function JsonData(eventType As Integer, day As Byte) As String

            Dim data As New Request()
            Dim arguments As New Parameter()
            Dim tm As DateTime = Now

            arguments.filter = New MarketFilter()
            arguments.filter.eventTypeIds = {eventType.ToString()}
            arguments.filter.turnInPlayEnabled = True

            arguments.filter.marketStartTime = New TimeRange()
            Dim start As DateTime = tm.AddMinutes(-120)
            Dim last As DateTime = start.AddDays(day)
            arguments.filter.marketStartTime.from = New Date(start.Year, start.Month, start.Day, start.Hour, 0, 0)
            arguments.filter.marketStartTime.to = New Date(last.Year, last.Month, last.Day, 23, 59, 0)

            data.params = arguments

            Return JsonConvert.SerializeObject(data)

            End Function
            Private Class Request
            Public Property jsonrpc As String = "2.0"
            Public Property method As String = "SportsAPING/v1.0/listEvents"
            Public Property params As Parameter
            Public Property id As Integer = 1
            End Class

            Private Class Parameter
            Public Property filter As MarketFilter
            End Class

            Private Class MarketFilter
            Public Property eventTypeIds As String()
            Public Property turnInPlayEnabled As Boolean
            Public Property marketCountries As String()
            Public Property marketStartTime As TimeRange
            End Class

            Public Class TimeRange
            Public Property from As Date
            Public Property [to] As Date
            End Class

            Private Class J_Response
            Public Property jsonrpc As String
            Public Property result As List(Of Event_Summary)
            Public Property id As Integer
            End Class

            Private Class Event_Summary
            Public Property [event] As Event_Info
            Public Property marketCount As Integer
            End Class

            Private Class Event_Info
            Public Property id As String
            Public Property name As String
            Public Property countryCode As String
            Public Property timezone As String
            Public Property openDate As String
            End Class
            Last edited by Peter Simple; 17-03-2014, 11:12 AM.

            Comment

            • HappyHatter1
              Junior Member
              • Sep 2011
              • 1

              #7
              Thank you this thread has been very helpful . I have a newbie question that I hope someone will help me with. I can get the response and have desearlised into the nested classes as suggested but, what code would i use to display the event types in simple listbox e.g. Market name followed by the id ?

              Comment

              • Peter Simple
                Junior Member
                • Aug 2009
                • 32

                #8
                Sub Generate_CalMenu()
                For i As Integer = 0 To today.Count - 1
                CalMenu.Items.Add(TimeConverter(today(i).time) & "-" & today(i).name)
                Next
                End Sub
                CalMenu is a WPF-Listbox and "today" is a list of events which are processed EventType results. To give you an idea how i process the api answer i give you here some simplified code because my App is little bit more complex.


                Code:
                Dim res As J_Response = JsonConvert.DeserializeObject(Of J_Response)(api_answer)
                
                        For i = 0 To .result.Count - 1
                            Dim ag As New Agenda
                            ag.id = res.result(i).event.id
                            ag.name = res.result(i).event.name
                            ...
                            EventSchedule.Add(ag)
                        Next
                Agenda is a class which i use to save the datas from the API and which has also some other tasks. EventSchedule is a list of Agendas which i need on various places. So then there is a link between "EventSchedule" and "today" but the reason for this is hidden in the construction of my App and does here not maater. But you could use "EventSchedule" to fill your listbox.

                Comment

                • Guest

                  #9
                  Originally posted by Peter Simple View Post
                  A last hint:

                  When you work with MarketFilters you can define a time range, e.g.

                  Code:
                  Public Class MarketFilter
                  
                      Public Property textQuery As String
                      Public Property eventTypeIds As Integer()
                      Public Property turnInPlayEnabled As Boolean
                      Public Property inPlayOnly As Boolean
                      Public Property marketCountries As String()
                      Public Property marketTypeCodes As String()
                      [B]Public Property marketStartTime As TimeRange
                  [/B]
                  End Class
                  Hi Peter - Mate thanks for helping me out so far. Its great that there are people in the forum willing to help.

                  Hey with the classes you have created such as the MarketFilter Class, why don't you use the ones Betfair have provided which I have included below for MarketFilter ?

                  Code:
                  Imports System
                  Imports System.Collections.Generic
                  Imports System.Linq
                  Imports System.Text
                  Imports Newtonsoft.Json
                  
                  Namespace API_NG.TO
                      Public Class MarketFilter
                          <JsonProperty(PropertyName:="textQuery")> _
                          Public Property TextQuery() As String
                  
                          <JsonProperty(PropertyName:="exchangeIds")> _
                          Public Property ExchangeIds() As ISet(Of String)
                  
                          <JsonProperty(PropertyName:="eventTypeIds")> _
                          Public Property EventTypeIds() As ISet(Of String)
                  
                          <JsonProperty(PropertyName:="eventIds")> _
                          Public Property EventIds() As ISet(Of String)
                  
                          <JsonProperty(PropertyName:="competitionIds")> _
                          Public Property CompetitionIds() As ISet(Of String)
                  
                          <JsonProperty(PropertyName:="marketIds")> _
                          Public Property MarketIds() As ISet(Of String)
                  
                          <JsonProperty(PropertyName:="venues")> _
                          Public Property Venues() As ISet(Of String)
                  
                          <JsonProperty(PropertyName:="bspOnly")> _
                          Public Property BspOnly() As Boolean?
                  
                          <JsonProperty(PropertyName:="turnInPlayEnabled")> _
                          Public Property TurnInPlayEnabled() As Boolean?
                  
                          <JsonProperty(PropertyName:="inPlayOnly")> _
                          Public Property InPlayOnly() As Boolean?
                  
                          <JsonProperty(PropertyName:="marketBettingTypes")> _
                          Public Property MarketBettingTypes() As ISet(Of MarketBettingType)
                  
                          <JsonProperty(PropertyName:="marketCountries")> _
                          Public Property MarketCountries() As ISet(Of String)                      
                  
                          <JsonProperty(PropertyName:="marketTypeCodes")> _
                          Public Property MarketTypeCodes() As ISet(Of String)
                  
                          <JsonProperty(PropertyName:="marketStartTime")> _
                          Public Property MarketStartTime() As TimeRange
                  
                          <JsonProperty(PropertyName:="withOrders")> _
                          Public Property WithOrders() As ISet(Of OrderStatus)
                  
                      End Class
                  End Namespace

                  Comment

                  • Peter Simple
                    Junior Member
                    • Aug 2009
                    • 32

                    #10
                    The answer is simple: i have not seen it. I was happy to find a working solution.

                    Comment

                    • JayBee
                      Junior Member
                      • Oct 2010
                      • 114

                      #11
                      Has anyone written an async version of the httpwebrequest to the Betfair server?

                      There are examples on the web but they don't work as they don't quite match what we are doing here. I've tried all kinds of combinations.

                      Thanks.

                      Comment

                      • maxspeed
                        Junior Member
                        • Aug 2014
                        • 6

                        #12
                        please help

                        to Peter :
                        could you please post this sample fully in one file?
                        i make step by step but fail
                        cant understand which step i do wrong
                        thank you

                        Comment

                        • Protagor
                          Junior Member
                          • Sep 2014
                          • 2

                          #13
                          Peter Simple has closed his account because he lives in a jurisdiction where Betfair is no longer available. Perhpas you post the code where you run in an error.

                          Comment

                          Working...
                          X