英文:
How to access response header in Graph v5.0 SDK?
问题
当我尝试将Graph SDK升级到v5.0时,我在升级用户密码重置时遇到了问题。根据文档,你可以像这样发送用户定义的密码:
POST https://graph.microsoft.com/v1.0/users/6ea91a8d-e32e-41a1-b7bd-d2d185eed0e0/authentication/passwordMethods/28c10230-6103-485e-b985-444c60001490/resetPassword
Content-type: application/json
{
"newPassword": "Cuyo5459"
}
不幸的是,SDK目前不支持此调用,我们必须手动构建请求并发送它:
var requestInfo = serviceClient.Users[userId].Authentication.PasswordMethods[passwordMethod.Id].ToGetRequestInformation();
requestInfo.HttpMethod = Microsoft.Kiota.Abstractions.Method.POST;
requestInfo.URI = new Uri(requestInfo.URI, "/resetPassword");
requestInfo.Content = new MemoryStream(Encoding.UTF8.GetBytes($"{{\"newPassword\":\"{password}\"}}"));
问题出现在当我们尝试读取响应时。根据文档,你将得到一个空的响应体,头部包含一个位置URL:
HTTP/1.1 202 Accepted
Content-type: application/json
Location: https://graph.microsoft.com/v1.0/users/6ea91a8d-e32e-41a1-b7bd-d2d185eed0e0/authentication/operations/88e7560c-9ebf-435c-8089-c3998ac1ec51?aadgdc=DUB02P&aadgsu=ssprprod-a
{}
但是,如果我们通过图服务客户端的请求适配器自己发送请求,我们无法访问响应头部:
var passwordResult = await serviceClient.RequestAdapter.SendAsync(requestInfo, PasswordResetResponse.CreateFromDiscriminatorValue);
根据Kiota文档,应该可以注册一个IResponseHandler
,可能可以访问此信息,但我找不到有关如何为图服务客户端的单个特定请求注册这样的处理程序的任何信息。在文档中,你可以通过errorMapping
参数提供特定于响应状态代码的特殊序列化程序,但即使这也只是一个只能访问响应主体而不是响应头部的ParsableFactory<>
(如果我理解正确的话)。
那么,使用v5 Graph SDK,有什么方法可以访问响应头部呢?
英文:
While I'm trying to upgrade to the Graph SDK to v5.0 I'm running into an issue when upgrading the password reset of a user. According to the documenation you can send a user defined password like this:
POST https://graph.microsoft.com/v1.0/users/6ea91a8d-e32e-41a1-b7bd-d2d185eed0e0/authentication/passwordMethods/28c10230-6103-485e-b985-444c60001490/resetPassword
Content-type: application/json
{
"newPassword": "Cuyo5459"
}
Unfortunately this call is currently not supported within the SDK and we have to manually build the request and send it:
var requestInfo = serviceClient.Users[userId].Authentication.PasswordMethods[passwordMethod.Id].ToGetRequestInformation();
requestInfo.HttpMethod = Microsoft.Kiota.Abstractions.Method.POST;
requestInfo.URI = new Uri(requestInfo.URI, "/resetPassword");
requestInfo.Content = new MemoryStream(Encoding.UTF8.GetBytes($"{{\"newPassword\":\"{password}\"}}"));
The problem arises when it comes to read the response. According to the documenation you'll get an empty body and the header contains a location URL:
HTTP/1.1 202 Accepted
Content-type: application/json
Location: https://graph.microsoft.com/v1.0/users/6ea91a8d-e32e-41a1-b7bd-d2d185eed0e0/authentication/operations/88e7560c-9ebf-435c-8089-c3998ac1ec51?aadgdc=DUB02P&aadgsu=ssprprod-a
{}
But if we send the request by ourself through the request adapter of the graph service client, we can't access the response header:
var passwordResult = await serviceClient.RequestAdapter.SendAsync(requestInfo, PasswordResetResponse.CreateFromDiscriminatorValue);
According to the Kiota documenation it should be possible to register an IResponseHandler
and that could probably access this information, but I can't find anything about how to register such an handler for a single specific request in the graph service client. Also in the documentation you can provide through the errorMapping
parameter special serializers depending on the response status code, but even this would be just a ParsableFactory<>
that can only access the body and not the header of the response (if I understood it correctly).
So what approach can be taken by using the v5 Graph SDK to access the response header?
答案1
得分: 2
以下是翻译好的部分:
-
在查看
AsyncMonitor<T>
代码 时,我们可以看到在执行原始请求信息时可以使用NativeResponseHandler
:var requestInformation = new RequestInformation() { HttpMethod = Method.GET , UrlTemplate = this.monitorUrl}; var nativeResponseHandler = new NativeResponseHandler(); requestInformation.SetResponseHandler(nativeResponseHandler); await this.client.RequestAdapter.SendNoContentAsync(requestInformation, cancellationToken:cancellationToken).ConfigureAwait(false); using var responseMessage = nativeResponseHandler.Value as HttpResponseMessage;
-
在我提供的代码示例中,它看起来像这样:
var nativeResponseHandler = new NativeResponseHandler(); var requestInfo = serviceClient.Users[userInformations.UserPrincipalName].Authentication.PasswordMethods[passwordMethod.Id].ToGetRequestInformation(); requestInfo.HttpMethod = Method.POST; requestInfo.URI = new Uri(requestInfo.URI, "/resetPassword"); requestInfo.Content = new MemoryStream(Encoding.UTF8.GetBytes($"{{\"newPassword\":\"{password}\"}}")); requestInfo.SetResponseHandler(nativeResponseHandler); var passwordResult = await serviceClient.RequestAdapter.SendAsync(requestInfo, PasswordResetResponse.CreateFromDiscriminatorValue); using var responseMessage = nativeResponseHandler.Value as HttpResponseMessage; var location = responseMessage.Headers.Location;
-
要在图形客户端中使用这些内容,当所需的方法可用但需要额外访问响应标头时,您可以使用类似于以下代码:
var nativeResponseHandler = a NativeResponseHandler(); await service.Drives[drive.Id].Items[sourceItem.Id].Copy.PostAsync(new CopyPostRequestBody { Name = sourceItem.Name, ParentReference = reference, }, config => config.Options.Add(new ResponseHandlerOption { ResponseHandler = nativeResponseHandler })); using var responseMessage = nativeResponseHandler.Value as HttpResponseMessage; var location = responseMessage.Headers.Location;
关于如何添加 ResponseHandlerOption
的信息已添加到 v5 升级指南 中。
英文:
By looking into the AsyncMonitor<T>
code we can see, that a NativeResponseHandler
can be used when performing raw request information:
var requestInformation = new RequestInformation() { HttpMethod = Method.GET , UrlTemplate = this.monitorUrl};
var nativeResponseHandler = new NativeResponseHandler();
requestInformation.SetResponseHandler(nativeResponseHandler);
await this.client.RequestAdapter.SendNoContentAsync(requestInformation, cancellationToken:cancellationToken).ConfigureAwait(false);
using var responseMessage = nativeResponseHandler.Value as HttpResponseMessage;
In my given code example it would look like this:
var nativeResponseHandler = new NativeResponseHandler();
var requestInfo = serviceClient.Users[userInformations.UserPrincipalName].Authentication.PasswordMethods[passwordMethod.Id].ToGetRequestInformation();
requestInfo.HttpMethod = Method.POST;
requestInfo.URI = new Uri(requestInfo.URI, "/resetPassword");
requestInfo.Content = new MemoryStream(Encoding.UTF8.GetBytes($"{{\"newPassword\":\"{password}\"}}"));
requestInfo.SetResponseHandler(nativeResponseHandler);
var passwordResult = await serviceClient.RequestAdapter.SendAsync(requestInfo, PasswordResetResponse.CreateFromDiscriminatorValue);
using var responseMessage = nativeResponseHandler.Value as HttpResponseMessage;
var location = responseMessage.Headers.Location;
To use this stuff within the graph client, when the desired method is available but you need to additionally access the response header, you could do this with code similar to:
var nativeResponseHandler = new NativeResponseHandler();
await service.Drives[drive.Id].Items[sourceItem.Id].Copy.PostAsync(new CopyPostRequestBody
{
Name = sourceItem.Name,
ParentReference = reference,
},
config => config.Options.Add(new ResponseHandlerOption { ResponseHandler = nativeResponseHandler }));
using var responseMessage = nativeResponseHandler.Value as HttpResponseMessage;
var location = responseMessage.Headers.Location;
The information about how to add the ResponseHandlerOption
has been added to the v5 upgrade guide.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论