-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Please provide a proxy-provider-asp-net-core sample for the new Graph SDK v5 with Kiota #22
Comments
I found a working solution but only tested it with the mgt-react person component and the two scopes "User.Read profile".
Therefore, implementing the proxy with System.Net.Http was the alternative, but I now had to take care of the correct auth header manually, which was done automatically before with the old v4 graphServiceClient: using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http.Headers;
using Microsoft.Extensions.Primitives;
using Microsoft.Graph;
using Microsoft.Identity.Web;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
namespace webapi.Controllers.api.v1
{
[Authorize]
[Route("[controller]")]
[ApiController]
public class GraphProxyController : ControllerBase
{
private readonly HttpClient _httpClient;
private readonly ITokenAcquisition _tokenAcquisition;
public GraphProxyController(IHttpClientFactory httpClientFactory, GraphServiceClient graphServiceClient, ITokenAcquisition tokenAcquisition)
{
_httpClient = httpClientFactory.CreateClient();
_httpClient.BaseAddress = new Uri(GetBaseUrlWithoutVersion(graphServiceClient));
_tokenAcquisition = tokenAcquisition;
}
[HttpGet("{*all}")]
public async Task<IActionResult> GetAsync(string all)
{
return await ProcessRequestAsync(HttpMethod.Get, all, null).ConfigureAwait(false);
}
[HttpPost("{*all}")]
public async Task<IActionResult> PostAsync(string all, [FromBody] object body)
{
return await ProcessRequestAsync(HttpMethod.Post, all, body).ConfigureAwait(false);
}
[HttpDelete("{*all}")]
public async Task<IActionResult> DeleteAsync(string all)
{
return await ProcessRequestAsync(HttpMethod.Delete, all, null).ConfigureAwait(false);
}
[HttpPut("{*all}")]
public async Task<IActionResult> PutAsync(string all, [FromBody] object body)
{
return await ProcessRequestAsync(HttpMethod.Put, all, body).ConfigureAwait(false);
}
[HttpPatch("{*all}")]
public async Task<IActionResult> PatchAsync(string all, [FromBody] object body)
{
return await ProcessRequestAsync(HttpMethod.Patch, all, body).ConfigureAwait(false);
}
private async Task<IActionResult> ProcessRequestAsync(HttpMethod method, string all, object content)
{
// Construct the full Graph API request URL with query string
var requestUri = $"{all}{Request.QueryString.ToUriComponent()}";
var requestMessage = new HttpRequestMessage(method, requestUri);
var scopes = new[] { "User.Read", "profile" };
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes);
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var headersToForward = new[] { "If-Match", "ConsistencyLevel" };
foreach (var headerKey in headersToForward)
{
if (Request.Headers.TryGetValue(headerKey, out StringValues headerValues))
{
requestMessage.Headers.TryAddWithoutValidation(headerKey, headerValues.ToArray());
}
}
if (content != null)
{
if (content is JObject jsonObject)
{
// Use Newtonsoft.Json to serialize JObject
var jsonContent = JsonConvert.SerializeObject(jsonObject);
requestMessage.Content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
}
else
{
// For other content types, use System.Text.Json
var jsonContent = System.Text.Json.JsonSerializer.Serialize(content);
requestMessage.Content = new StringContent(jsonContent, System.Text.Encoding.UTF8, "application/json");
}
}
var response = await _httpClient.SendAsync(requestMessage);
var responseBody = await response.Content.ReadAsStringAsync();
var contentType = response.Content.Headers.ContentType?.ToString() ?? "application/json";
return new ContentResult
{
Content = responseBody,
ContentType = contentType,
StatusCode = (int)response.StatusCode
};
}
private string GetBaseUrlWithoutVersion(GraphServiceClient graphClient)
{
var baseUrl = graphClient.RequestAdapter.BaseUrl;
var index = baseUrl.LastIndexOf('/');
return baseUrl.Substring(0, index);
}
}
} |
@Mnickii @andrueastman can you help with answering with the questions? It's very possible that Graph v5 is a little bit less suited for this scenario but I feel it's an interesting one. Would love your perspective. Thanks! |
Which components would you like this sample to be about?
Sample description
I am struggling to migrate the previous proxy provider from https://github.com/pnp/mgt-samples/tree/main/samples/app/proxy-provider-asp-net-core to the new Graph SDK with Kiota versions.
The versions I wanted to migrate to are:
I tried something like this, but the response is always null or I even get into the exception block with no helpful stacktrace in the case of $batch requests:
Are you willing to help?
Yes
The text was updated successfully, but these errors were encountered: