Search code examples
javahttpmicrosoft-graph-apiwebservice-client

Microsoft Graph: Requesting an Extension returns http 400 bad request


I added an open extension to an event in a calendar and am trying to read it back.

Here is the url:

https://graph.microsoft.com/v1.0/users/{userid}/calendars/{calendarId}=/events?$expand=Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event')

I cannot get this to work in a Java program. The following combinations do work:

  • It works my Java program if I remove the $expand... parameter. I can also ask for certain fields, that works too.
  • The request works in Postman (I just have to set the token)
  • The request works in Graph Explorer when I log in as the owner of the calendar

Here is the extension (inside one of the events) when I use Postman to read the event. It is the last item in the event:

        "extensions@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('{userid}')/calendars('{calendarId}')/events('{eventId})/extensions",
        "extensions": [
            {
                "@odata.type": "#microsoft.graph.openTypeExtension",
                "id": "Microsoft.OutlookServices.OpenTypeExtension.c.i.m.p.server.entities.outlook.Event",
                "extensionName": "c.i.m.p.server.entities.outlook.Event",
                "adherentId": "12346",
                "timeSlotID": "346463"
            }
        ]

Here is the Java code (Java 8, using java.io and java.net libraries):

    private static void doSomething(String _accessToken) throws IOException {
    String urlString = "https://graph.microsoft.com/v1.0/users/{userId}/calendars/{calendarId}/events?$expand=Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event')";

    URL url = new URL(urlString);

    Proxy webProxy 
  = new Proxy(Proxy.Type.HTTP, new InetSocketAddress({proxy-address}, {port}));
    HttpURLConnection connection = (HttpURLConnection) url.openConnection(webProxy);

    // Set the appropriate header fields in the request header.
    connection.setRequestProperty("Authorization", "Bearer " + _accessToken);
    connection.setRequestProperty("Accept", "application/json");

    connection.setDoOutput(true);
    connection.setReadTimeout(5000);
    connection.setRequestMethod(HttpMethod.GET);

    try {
        connection.connect();
        int responseCode = connection.getResponseCode();
        System.out.println("execute(), response code = " + responseCode);

        String responseMessage = connection.getResponseMessage();
        System.out.println("execute(), response Message = " + responseMessage);

        String responseString = null;
        try {
            InputStream ins = connection.getInputStream();
            BufferedReader br=new BufferedReader(new InputStreamReader(ins));
            StringBuffer sb=new StringBuffer();
            String line;
            while ((line=br.readLine()) != null) {
                sb.append(line);
            }
            responseString = sb.toString();
        } catch (Exception e) {
            System.out.println("Could not get input stream from response, error is " + e.toString());
        }

        System.out.println("execute(), httpResult = " + responseString);
    } catch (IOException e) {
        System.out.println(".execute(), IOException : " + e.toString());
    } finally {
        connection.disconnect();
    }
}

How do I fix this? Thanks!


Solution

  • 400 means bad request. It could be because of url encoding. Url encode the query string.

    Something like

    String query = "Extensions($filter=Id eq 'c.i.m.p.server.entities.outlook.Event'";
    String url = "https://graph.microsoft.com/v1.0/users/{userId}/calendars/{calendarId}/events?
                   $expand=" + URLEncoder.encode(query, StandardCharsets.UTF_8.name());
    

    Alternatively you could use graph service java api based on your need which will help abstract all the interactions for you or you could use any of the rest clients available.