Search code examples
vbscriptasp-classicxmlhttprequest

Passing a subscription key as a request header with msxml2.ServerXMLHTTP - Classic ASP/VB


I'm trying to pull data from an NHS API using a little bit of classic ASP (all I know I'm afraid) but am struggling to successfully pass the subscription key to the API.

The instructions are as follows:

  1. Pick a page on the NHS website, for example: https://www.nhs.uk/conditions/acne.
  2. Make a note of the path, for example: conditions/acne.
  3. Using a tool such as curl, Postman or your web browser, make a GET request to https://api.nhs.uk/content/acne with a valid subscription key subscription‑key: {subscription-key} in the request header.
  4. You’ll receive a JSON response structured using schema.org and the fields for this are explained in the following documentation....

From https://developer.api.nhs.uk/documentation/content-api

So, I wrote the following...

<%
Set xml = Server.CreateObject("MSXML2.ServerXMLHTTP")
xml.Open "GET", "https://api.nhs.uk/conditions/abdominal-aortic-aneurysm-screening/", False
on error resume next
xml.setRequestHeader "subscription‑key", "MY-API-KEY-HERE"
xml.setRequestHeader "Content-Type", "application/json"
xml.setRequestHeader "Accept", "application/json"
xml.Send
Response.Write "<h1>The HTML text</h1><xmp>"
Response.Write xml.responseText
Set xml = Nothing
%>

This just gives me the following response: { "statusCode": 401, "message": "Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API." }

They have example scripts in 5 different languages but not ASP or even ASP.NET

Any ideas what I can try to get this working?

Thanks

EDIT

Trying the method suggested here How can I post data using cURL in asp classic? ...

<%
Dim http: Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
Dim url: url = "https://api.nhs.uk/conditions/abdominal-aortic-aneurysm-screening/"
'Dim data: data = "something=this" - took this out as its a querystring for POST

With http
  Call .Open("GET", url, False)
  'Call .SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
  Call .SetRequestHeader("subscription‑key", "MY-API-KEY-HERE")
  'Call .Send(data) <- the data was the querystring, so not relevant here
  Call .Send()
End With

If Left(http.Status, 1) = 2 Then
  'Request succeeded with a HTTP 2xx response, do something...
Else
  'Output error
  Call Response.Write("Server returned: " & http.Status & " " & http.StatusText)
End If
%>

This gives me Invalid procedure call or argument: 'SetRequestHeader'

EDIT WITH SOLUTION

Working code with hyphen issue fixed...

<%
Dim http: Set http = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
Dim url: url = "https://api.nhs.uk/conditions/abdominal-aortic-aneurysm-screening/"

With http
  Call .Open("GET", url, False)
  Call .SetRequestHeader("subscription-key", "MYKEYHERE")
  Call .Send()
End With

If Left(http.Status, 1) = 2 Then
  'Request succeeded with a HTTP 2xx response, do something...
  Response.Write http.responseText
Else
  'Output error
  Call Response.Write("Server returned: " & http.Status & " " & http.StatusText)
End If
%>

Thanks Lankymart!


Solution

  • Tried your take on the duplicate example and it returned

    Invalid procedure call or argument: 'SetRequestHeader'

    This puzzled me as that code had been tested before and work fine so what changed? So I dug into the SetRequestHeader method calls.

    Turns out the error only occurs on this line;

    Call .SetRequestHeader("subscription‑key", "MY-API-KEY-HERE")
    

    In the end, removed subscription‑ from the header name and it worked without causing a compilation error.

    That led me to check the hyphen in the code using Asc("‑") and comparing that with a standard hyphen and sure enough they are different.

    <%
    Response.Write Asc("‑") & "<br />" 'From the code
    Response.Write Asc("-") & "<br />" 'Standard hyphen
    %>
    

    Output:

    -15454
    45
    

    Replaced the character with a standard hyphen the error has gone and the code runs returning;

    Server returned: 401 Unauthorized