How to put the parametrs correct in the JSON request

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • thebettrader
    Junior Member
    • Apr 2016
    • 35

    #1

    How to put the parametrs correct in the JSON request

    Hello,

    I try to do my first request to list the:
    "listMarketCatalogue"

    for a Tennis game. For this test I have manually looked up the eventid in this URL which is a tennis game 2016-04-23
    https://www.betfair.com/exchange/ten...nt?id=27769832

    I beleive something with the JSON is wrong formatted. If it would be possible to find out how I put the information wrong in the string, then I possibly can understand how the format should look like for many other requests?

    I get this error message when trying to send the request:
    The remote server returned an error: (400) Bad Request.

    //C# code
    Code:
          String appkey = "appkey";
                String sessiontoken = "sessiontoken ";
                HttpWebRequest request = WebRequest.Create("https://api.betfair.com/exchange/betting/json-rpc/v1/") as HttpWebRequest;
                request.Accept = "application/json";
                request.Method = "POST";
                request.KeepAlive = true;
                request.ContentType = "application/json";
                request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
                request.Headers.Add("Accept-Encoding", "gzip,deflate");
                request.Headers.Add("X-Application", appkey); //App key
                request.Headers.Add("X-Authentication", sessiontoken );
    
                //Create the message and add it to the web request
                string data = "{\"jsonrpc\": \"2.0\", \"method\": \"SportsAPING/v1.0/listMarketCatalogue\", \"params\": " +
                              "{\"filter\":{" +
    
                               "\"eventTypeIds\": [\"2\"], " + //Tennis
                               "\"eventIds\": [\"27769832\"] " + //Tennis game id
    
                              "}," +
                              "{\"marketProjection\": " +
    
                              "[\"RUNNER_DESCRIPTION\",\"RUNNER_METADATA\"]" +
    
                              "}," +
                              "{\"maxResults\": " +
                              
                              "\"20\"" +                          
                              
                              "}}, \"id\": 1}";
                
                using (var streamWriter = new StreamWriter(request.GetRequestStream()))
                {
                    streamWriter.Write(data);
                    streamWriter.Flush();
                    streamWriter.Close();
                }
                //The remote server returned an error: (400) Bad Request.
                String responseBody = "";
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    var stream = response.GetResponseStream();
                    responseBody = "";
                    using (var reader = new StreamReader(stream))
                    {
                        responseBody = reader.ReadToEnd();
                        reader.Close();
                    }
                    response.Close();
                    response.Dispose();
                }
                MessageBox.Show(responseBody);
    Thank you!
    Last edited by thebettrader; 22-04-2016, 10:00 PM.
  • jabe
    Senior Member
    • Dec 2014
    • 705

    #2
    EventIds are entirely unique, so there is no need to specify EventsTypeIds when you specify EventIds. However, I don't think that's the cause of the problem.

    You've put curly brackets around marketProjection and maxResults. I believe they need removing, so that would make the last few parts of your JSON string look like this:

    "\"marketProjection\": " +
    "[\"RUNNER_DESCRIPTION\",\"RUNNER_METADATA\"]," +
    "\"maxResults\": " +
    "\"20\"" +
    "}, \"id\": 1}"

    (I hope I've changed that as I meant to!)

    See here:

    https://api.developer.betfair.com/se...ketinformation

    https://api.developer.betfair.com/se...arketCatalogue

    Comment

    • thebettrader
      Junior Member
      • Apr 2016
      • 35

      #3
      Thanks Jabe, you did solve the problem.
      I think I start to understand better now how it is built up.

      One thing I do wonder is if it is possible to know when to use brackets[]
      or curly brackets{} ?
      For example on this link:
      https://api.developer.betfair.com/se...arketCatalogue

      I am not sure if it is written out to use curly brackts for: "filter"
      and only brackts for: "MarketFilter" or perheps one will learn which ones that use either in other calls and parameters also?

      Comment

      • jabe
        Senior Member
        • Dec 2014
        • 705

        #4
        Originally posted by thebettrader View Post
        I am not sure if it is written out to use curly brackts for: "filter"
        and only brackts for: "MarketFilter" or perheps one will learn which ones that use either in other calls and parameters also?
        You're welcome. It's not easy having to deal with all this new information.

        The w3c website has a tutorial on JSON strings (http://www.w3schools.com/json/). However...


        Basically, straight brackets denote an array (or collection).

        Curly brackets denote items that are part of a larger item, such as an object or a structure, or whatever else there might be.

        As an example, you might have an array showing the days in each month of the year, like this
        [{"January",31},{"February",28},{"March",31},{"Apri l",30},{etc!}]

        It is possible to have empty brackets too, and variables are often optional. When you create all the classes that you'll use in your program, you'll find that some of the data types are other classes and some of the data items are arrays (or collections, etc). Often the returned data will omit items. When you retrieve odds for a market, for example, there might be 3 back prices and 3 lay prices (which will include the odds and the amount of money available at each price), but sometimes there might be no lay odds at all, and fewer back odds.

        Runners is another set of similar data, perhaps containing name, number, etc, etc.

        Comment

        • jabe
          Senior Member
          • Dec 2014
          • 705

          #5
          Originally posted by thebettrader View Post
          Thanks Jabe, you did solve the problem.
          I think I start to understand better now how it is built up.

          One thing I do wonder is if it is possible to know when to use brackets[]
          or curly brackets{} ?
          For example on this link:
          https://api.developer.betfair.com/se...arketCatalogue

          I am not sure if it is written out to use curly brackts for: "filter"
          and only brackts for: "MarketFilter" or perheps one will learn which ones that use either in other calls and parameters also?
          The documentation, which you can download as a PDF, has examples of most API calls. There are occasional new releases of the documentation. Searching the forum can help too.

          Sometimes it may be helpful to look at the way the examples of calls appear in the sample code for other languages.

          Comment

          • betdynamics
            Junior Member
            • Sep 2010
            • 534

            #6
            You will make life a lot easier if you create classes for the messages that you want to use and then use JSON serialisation/deserialisation for conversion of the class into JSON (and vice versa).

            I would suggest that you take a look at something like "Programming for Betfair" by James Butler, as this will guide you through the process.

            The book is written for VB.Net but the examples are easily transferable to C#.

            Comment

            • jabe
              Senior Member
              • Dec 2014
              • 705

              #7
              Originally posted by betdynamics View Post
              You will make life a lot easier if you create classes for the messages that you want to use and then use JSON serialisation/deserialisation for conversion of the class into JSON (and vice versa).
              Very true.

              Also, creating all the classes, even though it can take a long time, will tell you where all the different data is to be found.

              Comment

              • thebettrader
                Junior Member
                • Apr 2016
                • 35

                #8
                Yes, it is a good idéa to create classes. I thought I will put some basic functions in classes so it is possible to call them/retreive information to work with.
                Yes it is quite many parameters to learn and know what they mean and how to do the calls. That makes it much more organized.
                I am familiar how to serialize and parse out the JSON responses so that will not be any problem.

                Looking at examples in the forum can help out also even that it is other languages which can give a clue. I am browsing around also.

                Thank you

                Comment

                • jabe
                  Senior Member
                  • Dec 2014
                  • 705

                  #9
                  Originally posted by thebettrader View Post
                  Yes, it is a good idéa to create classes. I thought I will put some basic functions in classes so it is possible to call them/retreive information to work with.
                  Yes it is quite many parameters to learn and know what they mean and how to do the calls. That makes it much more organized.
                  I am familiar how to serialize and parse out the JSON responses so that will not be any problem.

                  Looking at examples in the forum can help out also even that it is other languages which can give a clue. I am browsing around also.

                  Thank you
                  Good, glad to hear you have the serialize/deserialise sorted. On that topic, you may need to be aware that if you use the navigation file, you may need to increase the maximum length setting of the deserializer. I haven't got the navigation file to deserialize yet; fortunately I don't need it. I intend to post about this in the near future.

                  If you use a Timer control, I should warn you that the Timer1.interval value, which appears to allow you to set the number of milliseconds between it triggering a Timer1.Tick, cannot be set accurately. Certainly not to 1/1000 of a seconds

                  I will post again on this presently. The control will trigger no more than around 65 times a second. The minimum interval is between 15 and 16ms. Larger intervals tend to be, approximately, multiples of this interval (eg: approximately 31ms, 47ms, 61ms, etc).

                  There may be other intervals available (>16ms, but not multiples of the figure above), but I need to test those on other PCs before I post.

                  Comment

                  • thebettrader
                    Junior Member
                    • Apr 2016
                    • 35

                    #10
                    Thats nice, I have now succeed to parse out odds and avaliable amounts 3 depths down and put a series of classes into place to get the basic functionality to call to get information to work with.

                    I had got some problem to return getAccountFunds correctly but will do another thread to see what could be wrong with the JSON body.

                    Yes, I beleive I remember something like that about the timer control also, that it is not accurate on the millisecond. One reason perheps that windows isn't a realtime OS while Linux is if I remember correct?
                    Also the Thread.Sleep(1) will not be 1 millisecond sleep but rather about 15 milliseconds etc.

                    Comment

                    • Nick JD
                      Junior Member
                      • Jan 2015
                      • 47

                      #11
                      I found initially dealing with json difficult - just the process of cascading down to the data I actually needed was frustrating.

                      Simply posting the json into a viewer immediately makes sense of how to dig down into it and retrieve what you are looking for.

                      Post some json in this and it suddenly becomes very easy how to retrieve data from the gobbledegook that is json. Get your dev code to spit out the "final" json and view it in a viewer and glitches will stand out.

                      http://jsonviewer.stack.hu/
                      Last edited by Nick JD; 24-04-2016, 12:33 AM.

                      Comment

                      • jabe
                        Senior Member
                        • Dec 2014
                        • 705

                        #12
                        Originally posted by thebettrader View Post
                        Yes, I beleive I remember something like that about the timer control also, that it is not accurate on the millisecond. One reason perheps that windows isn't a realtime OS while Linux is if I remember correct?
                        Also the Thread.Sleep(1) will not be 1 millisecond sleep but rather about 15 milliseconds etc.
                        I did some googling the other week and it appears that by using functions of the Windows MIDI processor library file (WINMM.DLL) it may be possible to get better accuracy. It would then be simple to trigger an event that does the same as Timer1.Tick() in .NET. I'll add that to my threatened thread when I get round to it.

                        Comment

                        • thebettrader
                          Junior Member
                          • Apr 2016
                          • 35

                          #13
                          Originally posted by jabe View Post
                          I did some googling the other week and it appears that by using functions of the Windows MIDI processor library file (WINMM.DLL) it may be possible to get better accuracy. It would then be simple to trigger an event that does the same as Timer1.Tick() in .NET. I'll add that to my threatened thread when I get round to it.
                          That is interesting, I didn't know about the MIDI processor library. Better accuracy is always interesting to learn how to do.

                          When it comes to Thread.Sleep(...) I usually rely on > 50 milliseconds and using a while(true) loop in combination with AutoResetEvent to instantly trigger a function that will do for example calculations.

                          Code:
                                      
                          AutoResetEvent autoresetevent = new AutoResetEvent(false);
                          autoresetevent.WaitOne(); //Wait for trigger
                          autoresetevent.Set(); //Trigger

                          Comment

                          • betdynamics
                            Junior Member
                            • Sep 2010
                            • 534

                            #14
                            Out of interest, why do you require such accuracy on the timer?

                            The odds are updated by Betfair every 200ms, so I can't immediately see why you would benefit from any better accuracy than offered by the standard timer.

                            Comment

                            • jabe
                              Senior Member
                              • Dec 2014
                              • 705

                              #15
                              Originally posted by betdynamics View Post
                              Out of interest, why do you require such accuracy on the timer?

                              The odds are updated by Betfair every 200ms, so I can't immediately see why you would benefit from any better accuracy than offered by the standard timer.
                              I probably don't, but I only realised I couldn't rely on its accuracy when I added code to make the Keep Alive call. I aimed to make the call within the four hour limit, but for testing I set it to five minutes. My timer was set to trigger every 10ms or 1/100 second, because the program handles lots of events (even though it doesn't do many calls) and I wanted to spread the load rather than have lots of things happen at the same time.

                              I have a tab page for messages from the program. The messages from the Keep Alive were happening every 9-10 minutes instead of every five. I thought I was counting a hundred lots of 10ms to get to a second, and then 60 of those to increment my minute counter, and when that reached 5, the Keep Alive should happen.

                              Okay, it's not a great problem that I can't do 10ms, but I now know that I need to change something or the Keep Alive will happen after the four hours, if I haven't already been disconnected. I also can't do 19 seconds, or 53, or lot of others I feel I should be able to do. It also has a bearing on other projects I might want to do.

                              As it happens, once past initialisation, my program averages one API call every 2 or 3 seconds. It is potentially keeping track of a couple of hundred football matches, however, even if it only checks the odds once every 5 or 10 minutes, or longer.

                              Comment

                              Working...
                              X