Skip to content

Instantly share code, notes, and snippets.

@vgrem
Last active May 23, 2021 20:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vgrem/37dbe4762851decda79e32f5943b4fe3 to your computer and use it in GitHub Desktop.
Save vgrem/37dbe4762851decda79e32f5943b4fe3 to your computer and use it in GitHub Desktop.
BatchRequest class for msgraph-sdk-dotnet
using Microsoft.Graph;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Graph.GraphClient.JsonBatchSupport
{
public class Query
{
public string Id { get; set; }
public IBaseRequest Request { get; set; }
public HttpMethod Method { get; set; }
public HttpContent Content { get; set; }
public bool IsJson { get; set; }
public List<string> DependsOn { get; set; }
}
public static class GraphServiceClientExtensionsAlt
{
public static async Task<List<object>> SendBatchAsync(this GraphServiceClient client, BatchRequest request)
{
var batchMessage = request.ToMessage(client);
await client.AuthenticationProvider.AuthenticateRequestAsync(batchMessage);
var response = await client.HttpProvider.SendAsync(batchMessage);
var content = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(content);
var entities = json["responses"].Select(data =>
{
var status = JsonConvert.DeserializeObject<Int32>((string)data["status"]);
if (status != 200)
return null;
var queryId = (string)data["id"];
var returnType = request[queryId];
if (returnType != null)
{
var entityPayload = JsonConvert.SerializeObject(data["body"]);
var entity = JsonConvert.DeserializeObject(entityPayload, returnType);
return entity;
}
return null;
});
return entities.ToList();
}
}
public class BatchRequest
{
private List<Query> _queries = new List<Query>();
private Dictionary<string, Type> _resultsTable = new Dictionary<string, Type>();
private Query _prevQuery = null;
public Type this[string queryId]
{
get
{
if(_resultsTable.ContainsKey(queryId))
return _resultsTable[queryId];
return null;
}
}
public void AddQuery(IBaseRequest request, HttpMethod method, HttpContent content = null, bool isJson = false,
Type returnEntityType = null)
{
var queryId = Guid.NewGuid().ToString();
if (returnEntityType != null)
_resultsTable[queryId] = returnEntityType;
var query = new Query()
{
Id = queryId,
Request = request,
Method = method,
Content = content,
IsJson = isJson,
};
if (_prevQuery != null)
query.DependsOn = new List<string>() { _prevQuery.Id};
_queries.Add(query);
_prevQuery = query;
}
/// <summary>
/// Construct JSON batch request https://developer.microsoft.com/en-us/graph/docs/concepts/json_batching
/// </summary>
/// <param name="client"></param>
/// <returns></returns>
public HttpRequestMessage ToMessage(GraphServiceClient client)
{
var batchMessage = new HttpRequestMessage();
batchMessage.RequestUri = new Uri("https://graph.microsoft.com/v1.0/$batch");
batchMessage.Method = HttpMethod.Post;
batchMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
dynamic payload = new ExpandoObject();
payload.requests = _queries.Select(qry =>
{
var message = qry.Request.GetHttpRequestMessage();
if (qry.Content != null)
{
var request = new
{
id = qry.Id,
method = qry.Method.ToString(),
url = message.RequestUri.AbsoluteUri.Replace(client.BaseUrl, string.Empty),
headers = qry.Content.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault()),
body = qry.IsJson
? qry.Content.ReadAsAsync<object>().Result
: qry.Content.ReadAsByteArrayAsync().Result,
dependsOn = qry.DependsOn
};
if (!qry.IsJson && !request.headers.ContainsKey("Content-Type"))
request.headers["Content-Type"] = "application/octet-stream";
return request;
}
return new
{
id = qry.Id,
method = qry.Method.ToString(),
url = message.RequestUri.AbsoluteUri.Replace(client.BaseUrl, string.Empty),
headers = (Dictionary<string,string>)null,
body = (object) null,
dependsOn = qry.DependsOn
};
});
var jsonPayload = client.HttpProvider.Serializer.SerializeObject(payload);
batchMessage.Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
return batchMessage;
}
}
}
@anomepani
Copy link

Vadim, Thanks for the quick response.
For batching using, I didn't find any documentation for how to use different actions, limited resources or blog is available. I found this gist which looks somewhat helpful to me.
However, I will take a look for sure with the provided link and if require wil post question on stackoverflow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment