Page 2 of 2 FirstFirst 12
Results 41 to 65 of 65

Thread: Help using JSON API that requires Authentication with JWT token

  1. #41

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    I think you read the API docs correctly the first time. There is a "/search/series" what is what we have been doing, and a "/series/{id}" which is the API you are looking at now. I added both Classes to the program just because it will also be needed later (If I can get the search series to work). I now have:

    Code:
    Public Class SearchSeriesResult
        Public Property aliases() As String
        Public Property banner As String
        Public Property firstAired As String
        Public Property id As Long
        Public Property network As String
        Public Property overview As String
        Public Property seriesName As String
        Public Property status As String
    End Class
    
    
    Public Class SeriesResults
        Public Property data() As SeriesResult
        Public Property errors As SeriesError
    End Class
    
    Public Class SeriesResult
        Public Property added As String
        Public Property airsDayOfWeek As String
        Public Property airsTime As String
        Public Property aliases() As String
        Public Property banner As String
        Public Property firstAired As String
        Public Property genre() As String
        Public Property id As Long
        Public Property imbId As String
        Public Property lastUpdated As Long
        Public Property network As String
        Public Property netwirkId As String
        Public Property overview As String
        Public Property rating As String
        Public Property runtime As String
        Public Property seriesID As Long
        Public Property seriesName As String
        Public Property siteRating As Long
        Public Property siteRatingCount As Long
        Public Property zap2itId As String
    End Class
    
    Public Class SeriesError
        Public Property invalidFilters() As String
        Public Property invalidLanguage As String
        Public Property invalidQueryParams() As String
    End Class
    Jim

    Quote Originally Posted by Sitten Spynne View Post
    OK. Either I COMPLETELY read the original JSON wrong, or there's been an API update and the format has changed. What you got back looked really different than what I remembered, so I just double checked. You are getting correct JSON based on today's documentation. So let's start over. We have to rethink how we do a "SearchBySeries" request.

    (APPARENTLY I picked entirely the wrong API here, but the answer is still really similar so I'm editing it to something that makes more sense!)

  2. #42

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    These are the classes I have now: (I added the SeriesResults for the next step (After the SearchSeriesResult works).
    I left a message earlier about the "/search/series" being the one we were working on, but it didn't post for some reason.

    Code:
    Public Class SearchSeriesResult
        Public Property aliases() As String
        Public Property banner As String
        Public Property firstAired As String
        Public Property id As Long
        Public Property network As String
        Public Property overview As String
        Public Property seriesName As String
        Public Property status As String
    End Class
    
    
    Public Class SeriesResults
        Public Property data() As SeriesResult
        Public Property errors As SeriesError
    End Class
    
    Public Class SeriesResult
        Public Property added As String
        Public Property airsDayOfWeek As String
        Public Property airsTime As String
        Public Property aliases() As String
        Public Property banner As String
        Public Property firstAired As String
        Public Property genre() As String
        Public Property id As Long
        Public Property imbId As String
        Public Property lastUpdated As Long
        Public Property network As String
        Public Property netwirkId As String
        Public Property overview As String
        Public Property rating As String
        Public Property runtime As String
        Public Property seriesID As Long
        Public Property seriesName As String
        Public Property siteRating As Long
        Public Property siteRatingCount As Long
        Public Property zap2itId As String
    End Class
    
    Public Class SeriesError
        Public Property invalidFilters() As String
        Public Property invalidLanguage As String
        Public Property invalidQueryParams() As String
    End Class

    Quote Originally Posted by Sitten Spynne View Post
    Huh, OK. I'm going back and editing because it's still sort of almost right, the only difference is the inner type now will have different properties. I'm going fix it!

    Done. Thanks for pointing it out, and reminding me that there's 2 different places VB might want you to put parenthesis on array brackets, and four different contexts, and not all placements are all valid in all contexts.

    It's simple scenarios like that that make VB so easy to learn compared to C#, what with its one place for array brackets. Who has time to memorize one rule when you could be memorizing at least four?

  3. #43
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Help using JSON API that requires Authentication with JWT token

    Yeah, you got a good read on it. I'm curious to see how the new stuff works.

    Note that '/series/{id}' is a new pattern for a REST call. You can sort of cheat it into the HTTP layer without adding a new call.

    For this kind of API endpoint, one of the variables is part of the URL, but not part of query parameters. I'm not sure exactly what an 'id' is in this context, maybe a number. So if you wanted stuff about the series with id "1234", the URL would be '/series/1234', plus any query parameters if needed.

    So you don't really need to add a new GET or POST method, just do a little magic on the URL before calling it. You could instead choose to do the URL magic inside the HTTP layer, but that'd require a new call. The "new call" way is probably the most architecturally pure, but occasionally I feel like "being pure" involves more work than it's worth.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  4. #44

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    I'm still not able to deserialize the search/series Json results. I am getting the error:

    Newtonsoft.Json.JsonReaderException was unhandled
    HResult=-2146233088
    LineNumber=4
    LinePosition=18
    Message=Unexpected character encountered while parsing value: [. Path 'data[0].aliases', line 4, position 18.
    Path=data[0].aliases


    When I execute the following code"
    Code:
    Dim responseObject = JsonConvert.DeserializeObject(Of SearchSeriesResults)(searchResults)
    The JSON Text looks like this:
    Code:
    {
      "data": [
        {
          "aliases": [
            "Big Bang"
          ],
          "banner": "graphical/80379-g15.jpg",
          "firstAired": "2007-09-24",
          "id": 80379,
          "network": "CBS",
          "overview": "What happens when hyperintelligent roommates Sheldon and Leonard meet Penny, a free-spirited beauty moving in next door, and realize they know next to nothing about life outside of the lab. Rounding out the crew are the smarmy Wolowitz, who thinks he's as sexy as he is brainy, and Koothrappali, who suffers from an inability to speak in the presence of a woman.",
          "seriesName": "The Big Bang Theory",
          "status": "Continuing"
        },
        {
          "aliases": [],
          "banner": "graphical/290555-g2.jpg",
          "firstAired": "2007-10-02",
          "id": 290555,
          "network": "Mega Channel",
          "overview": null,
          "seriesName": "Big Bang (Mega)",
          "status": "Ended"
        },
    I am wondering if it is having trouble with the extra white space in the brackets of aliases:

    Jim




    Quote Originally Posted by Sitten Spynne View Post
    Huh, OK. I'm going back and editing because it's still sort of almost right, the only difference is the inner type now will have different properties. I'm going fix it!

    Done. Thanks for pointing it out, and reminding me that there's 2 different places VB might want you to put parenthesis on array brackets, and four different contexts, and not all placements are all valid in all contexts.

    It's simple scenarios like that that make VB so easy to learn compared to C#, what with its one place for array brackets. Who has time to memorize one rule when you could be memorizing at least four?

  5. #45
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Help using JSON API that requires Authentication with JWT token

    I don't see a 'SearchSeriesResults' type in the code you've posted. I see 'SeriesResults', "SeriesResult", and "SearchSeriesResult". But I'm missing exactly the type I need to see to think about how the parser might be interpreting the data.

    At the same time, pay attention to Inferred. VB has some ridiculous, stupid rules about parenthesis because it made the ridiculous, stupid decision to use them for array indices.

    If you were using a "hard" language like C#, there would be one rule to remember: "Array of Something is always Something[]". But since VB is an "easy" language, you have to remember:
    • For fields/local variables, there are two valid syntaxes for declaring an array variable. "Public x() As Something", "Public x As Something()".
    • But only one is legal if you want to declare bounds: "Public x(3) As Something".
    • Properties need parenthesis by their names, so their array type indicator needs to be near the type: "Public Property X() As Something()".
    • It's illegal to declare array bounds for a property.

    So, since I was typing code by memory, I forgot that the property should be:
    Code:
    Public Property aliases() As String()
    Welcome to VB, where the only rule with no exceptions is "memorize the language reference".

    (There's a technical reason, but not a good one. There is a concept in .NET called 'indexers' that maps to something VB6 called "the default property". In C# the rule is "you have to give it a specific name that is invalid in any other context, and it's not legal to call it like a method". In VB the rule is "lol you can call it whatever you want, and even call it directly if you want, so since any property MIGHT be an indexer, EVERY property needs extra syntax. Just in case."

    Like I said, in VB if you MIGHT have to type something, you generally HAVE to. Even if it's obvious you don't need it.)
    Last edited by Sitten Spynne; Jun 19th, 2017 at 10:09 PM.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  6. #46

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    Sorry, I guess I missed that one.

    Code:
    Public Class SearchSeriesResults
        Public Property data() As SearchSeriesResult()
    End Class
    
    
    Public Class SearchSeriesResult
        Public Property aliases() As String
        Public Property banner As String
        Public Property firstAired As String
        Public Property id As Long
        Public Property network As String
        Public Property overview As String
        Public Property seriesName As String
        Public Property status As String
    End Class


    Quote Originally Posted by Sitten Spynne View Post
    I don't see a 'SearchSeriesResults' type in the code you've posted. I see 'SeriesResults', "SeriesResult", and "SearchSeriesResult". But I'm missing exactly the type I need to see to think about how the parser might be interpreting the data.

    At the same time, pay attention to Inferred. VB has some ridiculous, stupid rules about parenthesis because it made the ridiculous, stupid decision to use them for array indices.

    If you were using a "hard" language like C#, there would be one rule to remember: "Array of Something is always Something[]". But since VB is an "easy" language, you have to remember:
    • For fields/local variables, there are two valid syntaxes for declaring an array variable. "Public x() As Something", "Public x As Something()".
    • But only one is legal if you want to declare bounds: "Public x(3) As Something".
    • Properties need parenthesis by their names, so their array type indicator needs to be near the type: "Public Property X() As Something()".
    • It's illegal to declare array bounds for a property.

    So, since I was typing code by memory, I forgot that the property should be:
    Code:
    Public Property aliases() As String()
    Welcome to VB, where the only rule with no exceptions is "memorize the language reference".

    (There's a technical reason, but not a good one. There is a concept in .NET called 'indexers' that maps to something VB6 called "the default property". In C# the rule is "you have to give it a specific name that is invalid in any other context, and it's not legal to call it like a method". In VB the rule is "lol you can call it whatever you want, and even call it directly if you want, so since any property MIGHT be an indexer, EVERY property needs extra syntax. Just in case."

    Like I said, in VB if you MIGHT have to type something, you generally HAVE to. Even if it's obvious you don't need it.)

  7. #47
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Help using JSON API that requires Authentication with JWT token

    Update the aliases property in SearchSeriesResult too!
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  8. #48
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Help using JSON API that requires Authentication with JWT token

    Quote Originally Posted by JimAvanti View Post
    Sorry, I guess I missed that one.
    Jim,
    You might have also missed how you were supposed to alter your Class definitions amidst Sitten's daily anti VB rant....

    The syntax for declaring a Property as an array requires that the parentheses are placed after the name of the Type, not after the name of the Property.

    So lines like:
    Code:
    Public Property aliases() As String
    Public Property genre() As String
    Public Property invalidFilters() As String
    should be:
    Code:
    Public Property aliases As String()
    Public Property genre As String()
    Public Property invalidFilters As String()

    There are also a couple of typos in the names you are using for the Properties:
    'imbId' should be 'imdbId', and 'netwirkId' should be 'networkId'.


    And the documentation for the API seems to be a little off.
    For the /series/{id} endpoint, the object named "seriesId" seems to be returning a String, not a Long as documented.
    They have also added an 'addedBy' object.


    With this in mind, the following is my take on how you may want to define your Classes. I have highlighted the changes from your original code:
    Code:
    Public Class SearchSeriesResults
        Public Property data As SearchSeriesResult()
    End Class
    
    
    Public Class SearchSeriesResult
        Public Property aliases As String()
        Public Property banner As String
        Public Property firstAired As String
        Public Property id As Long
        Public Property network As String
        Public Property overview As String
        Public Property seriesName As String
        Public Property status As String
    End Class
    Code:
    Public Class SeriesResults
        Public Property data As SeriesResult
        Public Property errors As SeriesError
    End Class
    
    Public Class SeriesResult
        Public Property added As String
        Public Property addedBy As Nullable(Of Long)
        Public Property airsDayOfWeek As String
        Public Property airsTime As String
        Public Property aliases As String() 
        Public Property banner As String
        Public Property firstAired As String
        Public Property genre As String() 
        Public Property id As Long
        Public Property imdbId As String 
        Public Property lastUpdated As Long
        Public Property network As String
        Public Property networkId As String 
        Public Property overview As String
        Public Property rating As String
        Public Property runtime As String
        Public Property seriesID As String    '   documentation has this as Long
        Public Property seriesName As String
        Public Property siteRating As Long
        Public Property siteRatingCount As Long
        Public Property status As String 
        Public Property zap2itId As String
    End Class
    
    Public Class SeriesError
        Public Property invalidFilters As String() 
        Public Property invalidLanguage As String
        Public Property invalidQueryParams As String() 
    End Class

  9. #49

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    That did it. I am able to get the specific items now.

    Code:
            Dim responseObject = JsonConvert.DeserializeObject(Of SearchSeriesResults)(searchResults)
            TextBox1.Text = TextBox1.Text & vbCrLf & responseObject.data(0).id
    Thanks,
    Jim


    Quote Originally Posted by Inferrd View Post
    Jim,
    You might have also missed how you were supposed to alter your Class definitions amidst Sitten's daily anti VB rant....

    The syntax for declaring a Property as an array requires that the parentheses are placed after the name of the Type, not after the name of the Property.

    So lines like:
    Code:
    Public Property aliases() As String
    Public Property genre() As String
    Public Property invalidFilters() As String
    should be:
    Code:
    Public Property aliases As String()
    Public Property genre As String()
    Public Property invalidFilters As String()
    [/CODE]

  10. #50
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Help using JSON API that requires Authentication with JWT token

    Whew! Thanks for picking up all the extra ones, Inferrd.

    JimAvanti: get used to carefully comparing the names of your properties and the types of your properties to what you're seeing in the JSON and what you're seeing in the documentation. It doesn't seem like these people are very disciplined about keeping their API and documentation in sync. The first 90% of working with that kind of API is writing something that matches the documentation. The second 90% is figuring out what they ACTUALLY send you.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  11. #51

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    Going back to the working GetWithJwt function, I am trying to catch errors. I would like to read the StatusCode response from the WebRequest. There are some codes I would like to check on (401 if unauthorized, 404 if the search string is not found,...). If an error code happens on
    Code:
    Using response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
    then it never gets to check the statusCode. If I use "Try/Catch" then I can't check the StatusCode in the catch because it is only available in the Using. Is there a way of checking the resonse.stausCode if there is an error with GetResopnse?

    Jim

    Code:
    Public Function GetWithJwt(ByVal url As String, ByVal jwt As String, Optional ByVal parameters As Dictionary(Of String, String) = Nothing) As String
            Dim encodedUrl As String = url
            If parameters IsNot Nothing Then
                encodedUrl = CreateEncodedParameterizedUrl(url, parameters)
            End If
    
            ' Configure the request headers.
            Dim request As HttpWebRequest = CType(HttpWebRequest.Create(encodedUrl), HttpWebRequest)
            request.Method = "GET"
    
            ' Build the JWT string and add the right header.
            Dim jwtHeaderValue As String = String.Format("Bearer {0}", jwt)
            request.Headers.Add(HttpRequestHeader.Authorization, jwtHeaderValue)
    
            ' Read the response and its JSON payload.
            Try
                Using response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
                    If response.StatusCode <> HttpStatusCode.OK Then
                        Throw New ApplicationException("There was an error with the request.")
                    End If
    
                    Using responseStream As Stream = response.GetResponseStream()
                        Using reader As New StreamReader(responseStream, Text.Encoding.UTF8)
                            Return reader.ReadToEnd()
                        End Using
                    End Using
                End Using
            Catch ex As Exception
    
            End Try
    
        End Function

  12. #52
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Help using JSON API that requires Authentication with JWT token

    I don't really like how HttpWebRequest does this, in a lot of cases a non-200 status code isn't really an "error" so making you go through exception handling is a bother. Nonetheless, you have the tools you need.

    If you check the documentation for HttpWebRequest.GetResponse(), you'll find a list of exceptions it might throw. Handling all of them is important, but in this case you are writing code that needs to do something special for WebException, which is thrown when "an error occurred while processing the request".

    If that exception is thrown, then the HttpWebResponse was not actually created for the Using statement! You could have rearranged things to get access to that variable, but you would have found it was Nothing. Generally, methods in .NET either do what they say OR throw an exception. Anyway, peek at the WebException documentation. Read all of its properties. The most important one is Response, which gives you access to the WebResponse that WOULD HAVE been created. This is almost the same thing as an HttpWebResponse, and is probably safe to cast, but I don't know yet if you need to.

    So:
    Code:
    Try
        Using response As HttpWebResponse = ...
            ...
        End Using
    Catch ex As WebException
        Dim response As HttpWebException = CType(ex.Response, HttpWebException)
        Dim statusCode As HttpStatusCode = e.StatusCode
        If statusCode = HttpStatusCode.Unauthorized Then
            ...
        End If
    End Catch
    A good question: Why didn't I put a Using statement in the Catch block? I have a hunch you aren't supposed to. This HttpWebResponse belongs to the WebException. It's that type's responsibility to dispose of it. If I dispose of it, I might cause trouble. The examples on MSDN don't dispose of the response when they get it. THAT SAID, it might be an oversight, and they might not have thought about it. So if you're having problems, add a Using statement to make sure it gets disposed.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  13. #53

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    I was surprised to see a status code other than 200 handled as an exception error also. That is why I thought there was something wrong and added the try/catch. When I pass a search string it couldn’t find I got the correct code 404, but it halted the program before I could even check the code.

    Name:  Error.jpg
Views: 658
Size:  26.2 KB

    I will need to have GetWithJwt pass any errors back to SearchSeriesByName which will have to pass the error back to the main calling command. The problem will be that SearchSeriesByName returns an SearchSeriesResults object (not a string) so I may have to serialize an errorcode into responseObject. Am I over thinking this or is there a much simpler way to go? I could also have SearchSeriesByName return a non-deserialized JSON string and deserialize it from the main program, that way I could simply send back the string “401”, “404” etc…

    Jim


    Quote Originally Posted by Sitten Spynne View Post
    I don't really like how HttpWebRequest does this, in a lot of cases a non-200 status code isn't really an "error" so making you go through exception handling is a bother. Nonetheless, you have the tools you need.

  14. #54
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Help using JSON API that requires Authentication with JWT token

    Well, there's plenty of viable approaches. Solving puzzles like that and having an error strategy is part of the fun.

    You *could* choose to get what you want out of the WebException, then throw a more specific exception that holds just that data. Some people like this because they believe Exceptions are the only way you should handle errors. I don't like it, because Exceptions are generally for "unexpected" errors you're not sure how to recover from, and these are more predictable scenarios like "expired JWT".

    You could add properties to SearchSeriesResults to represent the errors. The JSON parser doesn't really care if there are properties on the object that aren't in the JSON (unless you're serializing, then you have to tell it to ignore them.)

    But what I like the best is to decide to add ANOTHER object to the hierarchy to represent "the results of making this request, which may be either a JSON string or some error information."

    I sure do like wrapping objects with other objects, don't I? I do this because I don't want any one object to have to think too hard about the things "above" it. I don't want the types that are meant to represent JSON to have extra non-JSON stuff on them. That makes it likely I'll screw up and mix the two.

    So I'd add an object:
    Code:
    Public Class ApiResponse
        
        Public Property Result() As String
        Public Property StatusCode() As Integer
    
    End Class
    So probably something like this:
    Code:
    Public Function GetWithJwt(...) As ApiResponse
        ...
    
        Try
        Using response As HttpWebResponse = ...
            Using responseStream...
                Using reader...
                    Dim responseData As String = reader.ReadToEnd()
                    Dim result As New ApiResponse()
                    result.StatusCode = 200
                    result.Result = result
                    Return result
                End Using
            End Using
        End Using
    Catch ex As WebException
        Dim response As HttpWebException = CType(ex.Response, HttpWebException)
        Dim responseData As String
        Using reader As ....
            responseData = reader.ReadToEnd()
        End Using
        Dim statusCode As HttpStatusCode = e.StatusCode
    
        Dim result As New ApiResult()
        result.Result = responseData
        result.StatusCode = CInt(statusCode)
    End Catch
    That bubbles up the notion of a status code, and the layer above can decide exactly how to parse the JSON based on it.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  15. #55

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    I tried changing the GetWithJwt function so that if there was an error it would return it as a string and then the calling TvDbApi function could handle it by altering the Json text (id = 99999, and seriesName equal to the error code). That way it would pass back to any calling routine as valid JSON data, but building the JSON string was not easy with all the quotes involved so I gave up and just returned a Non-JSON string with the error.
    Code:
    Public Function GetWithJwt(ByVal url As String, ByVal jwt As String, Optional ByVal parameters As Dictionary(Of String, String) = Nothing) As String
            Dim encodedUrl As String = url
            If parameters IsNot Nothing Then
                encodedUrl = CreateEncodedParameterizedUrl(url, parameters)
            End If
    
            ' Configure the request headers.
            Dim request As HttpWebRequest = CType(HttpWebRequest.Create(encodedUrl), HttpWebRequest)
            request.Method = "GET"
    
            ' Build the JWT string and add the right header.
            Dim jwtHeaderValue As String = String.Format("Bearer {0}", jwt)
            request.Headers.Add(HttpRequestHeader.Authorization, jwtHeaderValue)
    
            Try
                Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
                Using responseStream As Stream = response.GetResponseStream()
                    Using reader As New StreamReader(responseStream, Text.Encoding.UTF8)
                        Return reader.ReadToEnd()
                    End Using
                End Using
                response.Close()
                'Catch ex As WebException
                '   Return "Error " & ex.Message
            Catch ex As Exception
                Return "Error " & ex.Message
            End Try
        End Function
    End Class
    The calling routine was also changed to return a string instead of a JSON object:
    Code:
        Public Function SearchSeriesByName(ByVal jwt As String, ByVal searchTerm As String) As String
            Dim restClient As New RestClient()
            Dim url As String = "https://api.thetvdb.com/search/series"
            Dim parameters As New Dictionary(Of String, String)()
            parameters.Add("name", searchTerm)
            Dim responseJson As String = restClient.GetWithJwt(url, jwt, parameters)
            Return responseJson
        End Function
    I now deserialize in the main program:
    Code:
        Private Sub GetShowID()
            ListView_Results.Items.Clear()
            Dim tvDbApi As New TvDbApi()
            Dim searchResults As String = tvDbApi.SearchSeriesByName(jwt, TextBox_Name.Text)
    
            If searchResults.Substring(0, 5) <> "Error" Then
                TextBox_Error.Clear()
                Dim responseObject = JsonConvert.DeserializeObject(Of SearchSeriesResults)(searchResults)
                Dim counter As Integer = 0
                For Each row In responseObject.data
                   ListView_Results.Items.Add(responseObject.data(counter).seriesName)
                    ListView_Results.Items(counter).SubItems.Add(responseObject.data(counter).id.ToString)
                    counter = counter + 1
                Next
            Else
                TextBox_Error.Text = searchResults
            End If
        End Sub
    I like your way of doing it better and I may change it, but I wanted to move on to the next step (which is working!):
    Code:
        Public Function SearchSeriesById(ByVal jwt As String, ByVal searchTerm As String) As String
            Dim restClient As New RestClient()
            Dim url As String = "https://api.thetvdb.com/series/" & searchTerm
            'Form1.TextBox_Token.Text = url
            Dim responseJson As String = restClient.GetWithJwt(url, jwt)
            Return responseJson
        End Function
    Code:
        Private Sub ListView_Results_MouseDoubleClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles ListView_Results.MouseDoubleClick
            TextBox_Info.Clear()
            TextBox_Info.Text = ListView_Results.SelectedItems(0).Text
            TextBox_Info.Text = TextBox_Info.Text & "   " & ListView_Results.SelectedItems(0).SubItems(1).Text
    
            Dim tvDbApi As New TvDbApi()
            Dim searchResults As String = tvDbApi.SearchSeriesById(jwt, ListView_Results.SelectedItems(0).SubItems(1).Text)
    
            If searchResults.Substring(0, 5) <> "Error" Then
                Dim responseObject = JsonConvert.DeserializeObject(Of SeriesResults)(searchResults)
                TextBox_Info.Text = TextBox_Info.Text & vbCrLf & responseObject.data.overview
                TextBox_Info.Text = TextBox_Info.Text & vbCrLf & "First Aired: " & responseObject.data.firstAired
                TextBox_Info.Text = TextBox_Info.Text & vbCrLf & "Network: " & responseObject.data.network
            Else
                TextBox_Error.Text = searchResults
            End If
        End Sub
    I hear what you are saying about the API documentation not being trusted: The seriesID does need to be a string rather than a Long. I was getting errors on some shows that respond with “”.

    I seem to be understanding just enough to get by for now.

    Thanks for all your help,
    Jim







    Quote Originally Posted by Sitten Spynne View Post
    Well, there's plenty of viable approaches. Solving puzzles like that and having an error strategy is part of the fun.

    You *could* choose to get what you want out of the WebException, then throw a more specific exception that holds just that data. Some people like this because they believe Exceptions are the only way you should handle errors. I don't like it, because Exceptions are generally for "unexpected" errors you're not sure how to recover from, and these are more predictable scenarios like "expired JWT".

    You could add properties to SearchSeriesResults to represent the errors. The JSON parser doesn't really care if there are properties on the object that aren't in the JSON (unless you're serializing, then you have to tell it to ignore them.)

    But what I like the best is to decide to add ANOTHER object to the hierarchy to represent "the results of making this request, which may be either a JSON string or some error information."

    I sure do like wrapping objects with other objects, don't I? I do this because I don't want any one object to have to think too hard about the things "above" it. I don't want the types that are meant to represent JSON to have extra non-JSON stuff on them. That makes it likely I'll screw up and mix the two.

  16. #56

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    Quote Originally Posted by Sitten Spynne View Post
    Huh, OK. I'm going back and editing because it's still sort of almost right, the only difference is the inner type now will have different properties. I'm going fix it!

    Done. Thanks for pointing it out, and reminding me that there's 2 different places VB might want you to put parenthesis on array brackets, and four different contexts, and not all placements are all valid in all contexts.

    It's simple scenarios like that that make VB so easy to learn compared to C#, what with its one place for array brackets. Who has time to memorize one rule when you could be memorizing at least four?
    Hello Sitten! You helped me out years ago when TheTVdb converted their API from XML to JSON. My program has been working great all these years, but they are now making major changes to the API again and I am running into problems again and was wondering if you are still around to help. This response is in the original message thread.

    The format of the Login response changed and now I am getting a null JWT token. If I look at the responseJson string I can see the token, but when I try to deserialize to get the token I seems empty.

    The old response string that worked is:
    {"token":"hhjkbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MTQzNzYzNjAsImlkIjoiVFZfQWlyRGF0ZSIsIm9ya WdfaWF0IjoxNjEzNzcxNTYwLCJ1c2VyaWQiOjk4NTM2LCJ1c2VybmFtZSI6IkppbUF2YW50aSJ9.HjputMMwKY4JeYft5Wqn99u1 H9mR90ooZkGxbhz4lfMoYUpPQpqQAG--LMl7VVlROHyszYHwAdSa1u1NHgJmjEMvE2Ijxfh8FOypgWbTEgKzdCATNn1NgSXgBYIIvKsF1JzkkH_0ieqdFTNOCr8fe2rOpV37 0g1lMl7MCKqn5OCs10u5TrDGnppQMltNPHHIyn4MsmQkKKhIgx9FnsCFYs117s5w5JvBW3Fm_9Q56tUzyfJtYEsOGp5--Bp6wlWEuEGkKscLf9A4ImIse45WRwmeL_EeGW8dtV9CTKEE1CnV4GRuTjDK2DISlbDTabkyBWD7x-T_KYVm9Ub7d_JBuA"}

    The new format is:
    {
    "status": "success",
    "data": {
    "token": "ddffbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlrZXkiOiJlNmU4YzhmMy0zODA5LTRjZjQtODA0Zi1iZDUyMGE4MmZjOT IiLCJjb21tdW5pdHlfc3VwcG9ydGVkIjpmYWxzZSwiZXhwIjoxNjE0MzcwNTg3LCJpZCI6IjAiLCJwaW4iOiJzdHJpbmcifQ.Ukh AlKa6urHCWWJikxHeYRthKRbU-nCaOdRl9dwkIGAAZuwLRPmE2nSj563JaMmANCbqgVIUUm8zhdHVMSwC68pz-AVfOOQx8uiPifnZWbkUHTnSbM4q5b7EiVUUx1gKZW-tqkYK91LCeqegfFZG12KWcE551hL4B9COuuBIt8Q30IA_on4GrIdtPjd4no2v11nPH9-mZJHeomj0ljK2dmeqSmWvXfHq0VUFWO7N8LMk8V0UrEaJObHrK57CD7Zvai7jDkvAUxySBbZ71iYcIRdo7z5vnNKA2sBUuuNb3lN tiN6ioTpGKbfAPhs9Ayk1AKyIWUfthDREbwzjD1eosCFrxN0PP0B0fM45owvxnFoWrlUpWEAIpIdYhtIqFRK9vB5CkEXRF9yMhbZ ewhMHYS-G_Ga5bCG9NxUNKXqclamowxg6WPYqJvukM2mtJk1sWMGt8P19R8Wz5nFrlDBljB28AfxKdHE7mMMThZ4zOIH0vNot2Nk60pizndB JQlPxfnxqhkeeqBr3qXL5OJXkLDK5IQuhtiJQeE3IYIXTIMpzpUTQ9HeFq0dilPFXtpDm7W1S2FyvrVJdNkozRYGuFXZMPrcpeev a95sW__dbz2CgfTRZByLsu86xAsSquvDchtXiv-vjJR0gBWXeFjx2ctWYrnPY10twnRyOvhBOXCc"
    }
    }


    This is the code being used. You can see the textBox I am displaying the results in. It seems that the property "token" is not being accessed correctly.
    Code:
    Public Class TvDbApi
    
        Public Function Login(ByVal credentials As TvDbCredentials) As String
            Dim restClient As New RestClient()
            Dim url As String = "https://api4.thetvdb.com/v4/login"
            Dim payloadJson As String = JsonConvert.SerializeObject(credentials)
            Dim responseJson As String = restClient.Post(url, payloadJson)
            Dim responseObject As LoginResult = JsonConvert.DeserializeObject(Of LoginResult)(responseJson)
            'Form1.TextBox_Token.Text = responseJson
            Form1.TextBox_Token.Text = responseObject.token
            Return responseObject.token
        End Function

  17. #57
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,715

    Re: Help using JSON API that requires Authentication with JWT token

    If you copy the JSON, open the Edit menu, Paste Special, and then select Paste JSON as Classes it will automatically generate a class representation of your JSON.

    Personally, I would rename Rootobject to Response and also capitalize the property names but use the JsonProperty decorator to map the lowercase response properties.

    This would leave you with a class representation of:
    Code:
    Public Class Response
        <JsonProperty("status")>
        Public Property Status As String
        <JsonProperty("data")>
        Public Property Data As Data
    End Class
    
    Public Class Data
        <JsonProperty("token")>
        Public Property Token As String
    End Class
    From here, you can still use the DeserializeObject method to get the token:
    Code:
    Public Function Login(ByVal credentials As TvDbCredentials) As String
        Dim restClient = New RestClient()
        Dim url = "https://api4.thetvdb.com/v4/login"
        Dim payloadJson = JsonConvert.SerializeObject(credentials)
        Dim responseJson = restClient.Post(url, payloadJson)
        Dim responseObject = JsonConvert.DeserializeObject(Of Response)(responseJson)
    
        Form1.TextBox_Token.Text = response.Data.Token
        Return responseObject.Data.Token
    End Function
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  18. #58

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    DDay9,

    Thanks! I don't quite understand what you did, but it worked! I'm going to try to figure out what you did because I'm sure I will need to make similar changes to the rest of the API calls. I also don't know what you mean by JsonProperty decorator or about pasting JSON as classes, but I will search that out later. I am using the vb.net 2010 so maybe those are features I don't have.

    Thanks for your help. Now I can push a bit more forward.

    Jim


    Quote Originally Posted by dday9 View Post
    If you copy the JSON, open the Edit menu, Paste Special, and then select Paste JSON as Classes it will automatically generate a class representation of your JSON.

    Personally, I would rename Rootobject to Response and also capitalize the property names but use the JsonProperty decorator to map the lowercase response properties.

    This would leave you with a class representation of:
    Code:
    Public Class Response
        <JsonProperty("status")>
        Public Property Status As String
        <JsonProperty("data")>
        Public Property Data As Data
    End Class
    
    Public Class Data
        <JsonProperty("token")>
        Public Property Token As String
    End Class
    From here, you can still use the DeserializeObject method to get the token:
    Code:
    Public Function Login(ByVal credentials As TvDbCredentials) As String
        Dim restClient = New RestClient()
        Dim url = "https://api4.thetvdb.com/v4/login"
        Dim payloadJson = JsonConvert.SerializeObject(credentials)
        Dim responseJson = restClient.Post(url, payloadJson)
        Dim responseObject = JsonConvert.DeserializeObject(Of Response)(responseJson)
    
        Form1.TextBox_Token.Text = response.Data.Token
        Return responseObject.Data.Token
    End Function

  19. #59
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,715

    Re: Help using JSON API that requires Authentication with JWT token

    Ah, yeah it is likely like that the Paste JSON as Classes doesn't exist in 2010.

    The JsonProperty decorator is the first line in this code:
    Code:
    <JsonProperty("status")>
    Public Property Status As String
    What it does when the DeserializeObject runs is say: I am looking for the "status" property in the JSON literal and I want to place the value in the "Status" property of the object.

    I only did this because the naming convention that I follow requires property names to be uppercased.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  20. #60
    Fanatic Member
    Join Date
    Jun 2019
    Posts
    557

    Re: Help using JSON API that requires Authentication with JWT token

    There is site which do the same job like paste as JSON: http://jsonutils.com/

    Actually, the project itself is written in .NET so you can build it and run it locally in the intranet as the site itself is not using HTTPS.

  21. #61

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    Quote Originally Posted by dday9 View Post
    Ah, yeah it is likely like that the Paste JSON as Classes doesn't exist in 2010.

    The JsonProperty decorator is the first line in this code:
    Code:
    <JsonProperty("status")>
    Public Property Status As String
    What it does when the DeserializeObject runs is say: I am looking for the "status" property in the JSON literal and I want to place the value in the "Status" property of the object.

    I only did this because the naming convention that I follow requires property names to be uppercased.
    Well, you pointed me in the right direction and with your comments I did some searching and found a website that automatically generates the JSON class from the API call results. https://jsonutils.com/

    With that I was able to get the next API call (Series name search) working. I am on a roll!
    I would never have figured out the class structure from the results I had on my own.

    Thanks for your help,

    Jim

  22. #62

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    Quote Originally Posted by peterst View Post
    There is site which do the same job like paste as JSON: http://jsonutils.com/

    Actually, the project itself is written in .NET so you can build it and run it locally in the intranet as the site itself is not using HTTPS.
    I just realized you told be about the jsonutil.com site after I searched and found it! I was able to do the next step which was an API call to search for a TV show and get the showID. I used jsonutil to convert the given Schema to a JSON class and it worked.

    Now I need to do an API call to get the Show details from the ShowID. The Schema they give on the website does not seem to convert to a JSON Class correctly. Could you take a look at it? I saw there is an update for VS WebToold2012 which adds the "Paste as JSON Class", but it is not for VS2010.

    This is the Schema they give:
    Code:
    {
      "data": {
        "abbreviation": {
          "String": "string",
          "Valid": true
        },
        "aliases": [
          {
            "language": "string",
            "name": "string"
          }
        ],
        "country": {
          "String": "string",
          "Valid": true
        },
        "defaultSeasonType": 0,
        "firstAired": {
          "String": "string",
          "Valid": true
        },
        "id": {
          "Int64": 0,
          "Valid": true
        },
        "image": {
          "String": "string",
          "Valid": true
        },
        "isOrderRandomized": true,
        "lastAired": {
          "String": "string",
          "Valid": true
        },
        "name": {
          "String": "string",
          "Valid": true
        },
        "nameTranslations": [
          "string"
        ],
        "nextAired": "string",
        "originalCountry": {
          "String": "string",
          "Valid": true
        },
        "originalLanguage": {
          "String": "string",
          "Valid": true
        },
        "overviewTranslations": [
          "string"
        ],
        "score": 0,
        "slug": {
          "String": "string",
          "Valid": true
        },
        "status": {
          "id": 0,
          "keepUpdated": true,
          "name": "string",
          "recordType": "string"
        }
      },
      "status": "string"
    }

    This is what jsonutils converts it to:
    Code:
     Public Class Abbreviation
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class Alias
            Public Property language As String
            Public Property name As String
        End Class
    
        Public Class Country
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class FirstAired
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class Id
            Public Property Int64 As Integer
            Public Property Valid As Boolean
        End Class
    
        Public Class Image
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class LastAired
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class Name
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class OriginalCountry
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class OriginalLanguage
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class Slug
            Public Property String As String
            Public Property Valid As Boolean
        End Class
    
        Public Class Status
            Public Property id As Integer
            Public Property keepUpdated As Boolean
            Public Property name As String
            Public Property recordType As String
        End Class
    
        Public Class Data
            Public Property abbreviation As Abbreviation
            Public Property aliases As Alias()
            Public Property country As Country
            Public Property defaultSeasonType As Integer
            Public Property firstAired As FirstAired
            Public Property id As Id
            Public Property image As Image
            Public Property isOrderRandomized As Boolean
            Public Property lastAired As LastAired
            Public Property name As Name
            Public Property nameTranslations As String()
            Public Property nextAired As String
            Public Property originalCountry As OriginalCountry
            Public Property originalLanguage As OriginalLanguage
            Public Property overviewTranslations As String()
            Public Property score As Integer
            Public Property slug As Slug
            Public Property status As Status
        End Class
    
        Public Class SearchBySeriesID
            Public Property data As Data
            Public Property status As String
        End Class
    It just doesn't look right to me.
    Thanks,
    Jim

  23. #63
    Fanatic Member
    Join Date
    Jun 2019
    Posts
    557

    Re: Help using JSON API that requires Authentication with JWT token

    Some names are reserved words for VB.NET so you have to use JsonProperty attribute and rename the variable to something not reserved. For example:
    VB.NET Code:
    1. Public Class OriginalCountry
    2.     Public Property String As String
    3.     Public Property Valid As Boolean
    4. End Class

    will become:
    VB.NET Code:
    1. Public Class OriginalCountry
    2.     <JsonProperty("String")> Public Property Country As String
    3.     Public Property Valid As Boolean
    4. End Class

    The attribute JsonProperty is telling Newtonsoft.Json library to put the value of String JSON property to OriginalCountry.Country property.

    This way you have to decorate all badly named JSON properties to something valid and more meaningful in your VB.NET classes. Rename the class Alias as it is also reserved word.

    It is also good style to rename _all_ classes and properties that are not in line with the rules you use in your VB.NET apps, e.g. class name and properties should use PascalCase naming convention. Meaningful names will make further development much easier as OriginalCountry.Country or FirstAired.FirstAiredDate (just put my own ones as I don't know what it is about) are better than using Country.String or FirstAired.String.

    If you want you can add conversion of strings to real dates in your properties by converting them to full properties with getter and setter and put the date to Date or DateTimeOffset if you are converting from Unix time milliseconds:
    VB.NET Code:
    1. Dim firstAired As DateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(123546)
    2. Dim firstAiredDate As Date = DateTimeOffset.FromUnixTimeMilliseconds(123546).DateTime

  24. #64

    Thread Starter
    Member
    Join Date
    Feb 2014
    Posts
    55

    Re: Help using JSON API that requires Authentication with JWT token

    Quote Originally Posted by Sitten Spynne View Post
    OK. We know how to convert objects to and from JSON. That's important to this project because any web API is mostly about sending and receiving JSON objects.

    I like to work in layers. To log in, I need to send some particular JSON to the server, and it's going to give me some JSON back. I don't want to muck about with HTTP types every time I do that. So I'm going to write a "RestClient" class to handle the HTTP bits for me. Let's have a look at the first draft:
    Code:
    Imports System.IO
    Imports System.Net
    
    Public Class RestClient
    
        Public Function Post(ByVal url As String, ByVal payload As String) As String
    
            ' Configure the request headers.
            Dim request As HttpWebRequest = CType(HttpWebRequest.Create(url), HttpWebRequest)
            request.Method = "POST"
            request.ContentType = "application/json"
    
            ' Send the request plus the JSON payload.
            Using requestStream As Stream = request.GetRequestStream()
                Using writer As New StreamWriter(requestStream, Text.Encoding.UTF8)
                    writer.Write(payload)
                End Using
            End Using
    
            ' Read the response and its JSON payload.
            Using response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
                If response.StatusCode <> HttpStatusCode.OK Then
                    ' This needs to be more sophisticated, you can flesh it out later.
                    Throw New ApplicationException("There was an error with the request.")
                End If
    
                Using responseStream As Stream = response.GetResponseStream()
                    Using reader As New StreamReader(responseStream, Text.Encoding.UTF8)
                        Return reader.ReadToEnd()
                    End Using
                End Using
            End Using
        End Function
    
    End Class
    This method takes the URL and some JSON. It sets up an HTTP POST request and sends the JSON along with it. It then reads the response, throws an exception if there was an error, or returns the JSON payload of the response.

    Why am I leaving the JSON as a string here? Why am I not using objects? Life is easiest if each method does only one thing. This method "sends a request and returns the response". That's about as close to "one thing" as an HTTP exchange can get. If I made a more generic version that worked with objects, it would, "Serialize an object to JSON, then send it as part of a REST request, then attempt to deserialize the response and return the deserialized object." That's more complicated. More complicated things are more likely to fail, and when they fail they're harder to debug.

    So I've got this RestClient class. How's this help me do something with the API? Well, I want to make using the API pretty easy. So I'd like a class that doesn't look like HTTP at all, and instead works with the objects I need to make to represent the JSON. When I look at the /login endpoint, I can describe it as "a function that takes some credentials and returns a JWT". In VB terms:
    Code:
    Public Function Login(ByVal credentials As TvDbCredentials) As String
    But wait. The '/login/ endpoint doesn't return a String. It returns a JSON string representing an object with a 'token' property (unless there's an error.) So I need to make an object to represent it:
    Code:
    Public Class LoginResult
        Public Property token As String
    End Class
    Armed with that, I can write a function that converts the TvDbCredentials to JSON, sends it to the /login endpoint, and returns the token from the result:
    Code:
    Imports Newtonsoft.Json
    
    Public Class TvDbApi
    
        Public Function Login(ByVal credentials As TvDbCredentials) As String
            Dim restClient As New RestClient()
            Dim url As String = "https://example.com/login"
            Dim payloadJson As String = JsonConvert.SerializeObject(credentials)
    
            Dim responseJson As String = restClient.Post(url, payloadJson)
            Dim responseObject As LoginResult = JsonConvert.DeserializeObject(Of LoginResult)(responseJson)
            Return responseObject.token
        End Function
    
    End Class
    See how small, neat, and easy to understand it is with the HTTP logic removed? At this point you ought to be able to get a JWT with a small test application:
    Code:
    Module Module1
    
        Sub Main()
            Dim credentials As New TvDbCredentials()
            credentials.apikey = "apikey asdf"
            credentials.username = "username asdf"
            credentials.userkey = "userkey asdf"
    
            Dim tvDbApi As New TvDbApi()
            Dim jwt As String = tvDbApi.Login(credentials)
            Console.WriteLine(jwt)
        End Sub
    
    End Module
    See the layers at work? You can log in and get the JWT without thinking about JSON or HTTP now. This is another good place for me to stop. Try this out. Make sure to change the URL from 'example.com' to the right one for TvDb, and make sure you know if you should be using https or just http. If the program prints a JWT, you're doing great and can continue. If there is an error, we have to fix that before moving on.

    The next post is going to try out a random entry point to demonstrate how we can take the code we already have and adjust it to include a JWT.

    Sitten Spynne,
    Hello, I hope you are still active in this forum. You have helped me transition my program from using an XML to JSON API from the TVdb back in 2017 and the program has been working like a charm all this time. That was version 2.0 or the API. The Tvdb.com is eliminating the old 2.0API very soon as they have rolled out version 4.0. The new version has a ton of changes including the addition on movies, but the 2.0 API key has been replaced by a developer key unique to a program as well as a user pin. I have already made these changes and I was able to get the JWT token in the early staged of 4.0 API. As the new API became finalized I was no longer able to get a valid token. I now get an error in ResrClient that I can't seem to get past (Could not create SSL/TSL secure channel). I am not sure if maybe Newtonsoft.json or VisualBasic.net needs some update to work with a secure API, or if it even has something to do with increased security. I hope you or someone can point me in the right direction.
    Thanks,
    Jim

    Name:  RestClient.jpg
Views: 222
Size:  23.4 KB

  25. #65
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,715

    Re: Help using JSON API that requires Authentication with JWT token

    Please open a new thread and link to this one.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

Page 2 of 2 FirstFirst 12

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width