Microsoft Graph 错误响应 - 如何从 JSON 中提取 HTTP 状态代码和内部错误代码? [英] Microsoft Graph Error Responses - How to extract HTTP Status Code and Inner Error Code from JSON?

查看:61
本文介绍了Microsoft Graph 错误响应 - 如何从 JSON 中提取 HTTP 状态代码和内部错误代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在我的 .NET Core 3.1 应用中测试 MS Graph .NET Core SDK 客户端.目的是提供我自己的本地 Web API 用户服务,用于从 Azure B2C AD 执行更新/更改/获取用户.

I'm currently testing the MS Graph .NET Core SDK Client in my .NET Core 3.1 app. Purpose is to provide my own local Web API user service that performs updates/changes/fetching of users from Azure B2C AD.

在我的预期解决方案中,我将拥有各种 HTTP 客户端微服务,它们将向我的用户服务 SDK 客户端调用 API 命令,而不是直接使用 REST 调用 Azure Graph API.

In my intended solution, I will have various HTTP Client micro-services that will call API commands to my user service SDK Client, as opposed to calling the Azure Graph API using REST directly.

在我的用户服务应用程序中,我试图通过对发送到 Azure 的实际 SDK 命令使用存储库/接口方法来保持干净.然后,这个相同的用户服务应用程序使用我自己的 WEB API 将数据返回到我的本地 HTTP 客户端.把这个用户服务应用想象成中间人效果.

In my user service app, I'm trying to keep things clean by using a repository/interface approach for the actual SDK commands that are sent off to Azure. This same user service app is then returning the data back to my local HTTP Clients using my own WEB API. Imagine this user service app as the man in the middle effect.

下图总结环境:

这样做的目的是在对图形服务使用的功能进行更改或添加时减少工作量,即在我自己的本地应用程序之间的通信中提供一些标准化,并促进更好的关注点分离.此外,如果 MS 对 Graph API 进行更改,那么我只会更新用户服务应用程序,而不是在我的所有 HTTP 客户端应用程序中更改代码.希望这是有道理的.

The purpose of this is to reduce the work when changes or additions are made to the features used with the Graph Service i.e provide some standardization in comms across my own local apps and to promote better separation of concerns. Also if MS make changes to the Graph API, then I'm only updating the user service app rather than making code changes across all my HTTP Client apps. Hope that makes sense.

无论如何,现在进入正题!我的问题的原因:

Anyway, now to the point! reason for my questions:

(请耐心等待,我是 REST 和使用接口的新手)

(bear with me here, I'm new to REST and using Interfaces)

在图形 SDK 客户端和 Azure 中的图形服务 API 之间遇到的任何错误都将记录在我的用户服务应用程序中,即我将在第一时间捕获大量 json 错误详细信息,但是我根本不需要传递这个级别的详细信息返回给我所有的本地调用 HTTP 客户端.

Any errors encountered between the Graph SDK Client and the Graph Service API in Azure will be logged within the my user service app i.e. the extensive json error details i will capture at the first opportunity, HOWEVER I simply don't need to pass this level of detail back to all my local calling HTTP Clients.

我想要实现的是一种识别/捕获在 SDK 客户端和图形服务之间遇到的任何 HTTP 状态代码错误的方法,以及错误的一些基本细节,即简短的描述和仅通过将这些较低级别的详细信息返回到我的本地 HTTP 客户端,即保持干净.

What I'm trying to achieve is a means of identifying/capturing any HTTP Status code errors that were encountered between the SDK Client and the Graph Service, along with perhaps some basic details of the error i.e a short description and only pass these lower level details back to my local HTTP Clients i.e, keep things clean.

我正在努力了解如何在我的代码中执行此操作,特别是考虑到我同时使用一个接口使其变得更加复杂的事实.MS 文档确实提供了有关使用图形服务的预期错误代码列表的信息,但没有示例说明如何处理此信息以将相关(但较轻的信息版本)传递回另一个来源.

I'm struggling with knowing how to do this in my code, especially given the fact that i'm using an interface at the same time is making it more complex. The MS docs does give info on the list of expected error codes to be had from using the graph service, but there is no examples that explains how to process this information in order to pass the relevant (but lighter version of the info) back to another source.

示例场景:

  1. 本地 HTTP 客户端调用 [HttpGet] GetUserById 到我的用户服务 Web API
  2. 然后,我的 Web API 使用图形 SDK 客户端与 Azure B2C 联系,获取数据并返回.
  3. 然后,我的 WEB API 应该检查收到的信息,如果发现用户很好,则将用户返回到我的调用 HTTP 客户端.
  4. 如果未找到用户,或者可能发出了错误的请求(缺少属性/错误的用户 ID 等),那么我需要检查收到的 HTTP 状态错误代码并将相同的错误代码传递回我的调用 HTTP 客户端,同时,我不想传回从 Graph Service 收到的大量 json 错误详细信息,而是想传回更简单的消息,例如找不到用户.
  5. 简化消息的合乎逻辑的方法是利用图服务提供的已经烘焙的代码消息:

如下所示:code"属性足以向任何调用 HTTP 客户端解释这种情况,如果我需要进一步调查,我会检查日志:

Like below: The "code" attribute is enough to explain the situation to any calling HTTP Client, if I need to investigate further then I would inspect the logs:

 {
   "error": {
     "code": "invalidRange",
     "message": "Uploaded fragment overlaps with existing data.",
     "innerError": {
       "requestId": "request-id",
       "date": "date-time"
     }
   }
 }

我只是不知道如何提取从通过 SDK 对图形服务的调用中接收到的 HTTP 状态代码,以及如何从正文中的 json 错误消息中获取单个属性然后返回这个以正确和一致的方式将减少/简化的信息返回到我自己的 HTTP 客户端.到目前为止,我自己的项目代码如下:

I just cant work out how to extract the HTTP Status code received from the the calls to the Graph Service through the SDK, as well as being able to fetch a single attribute from the json error message in the body and then return this reduced/simplified info back to my own HTTP Clients in the correct and conform ant manner. My own project code so far is below:

我的用户服务 WEB API 控制器:

My user service WEB API Controller:

    [HttpGet("{id}")]
    public async Task<IActionResult> GetUserById(string id)
    {
        try
        {
            var user = await _repository.GetUserByIdAsync(id);

        }
        catch(Exception ex) 
        {
            // What am I catching here? how do I get the HTTP Status Code that 
            was received from the call to the Graph Service in the event of an error?
            // How do i extract the code error key/value from the json received from Graph Service?
        }

        // Finally, how do I return this captured info to the HTTP Client?


        // Ignore this part, not sufficient for my needs.   
        //if (user == null) return BadRequest();
        //if (user != null) return Ok(user);
        //else return NotFound();
    }

我的界面:

namespace MicrosoftGraph_API.Repository
{
    public interface IGraphClientRepo
    {
        public Task<List<User>> GetAllUsersAsync();

        public Task<User> GetUserByIdAsync(string id); 
    }
}

我的图形 SDK 客户端类:

My Graph SDK Client Class:

public class GraphSDKClientRepo : IGraphClientRepo
{
    public readonly IUserServiceClient _IUserServiceClient;

    public GraphSDKClientRepo(IUserServiceClient userServiceClient)
    {
        _IUserServiceClient = userServiceClient;
    }

    public async Task<User> GetUserByIdAsync(string id)
    {
        var graphClient = _IUserServiceClient.InitializeGraphClient();

        // Get user by object ID
        var result = await graphClient.Users[id]
            .Request()
            .Select(e => new
            {
                e.DisplayName,
                e.Id,
                e.Identities
            })
            .GetAsync();

        return result;
    }
}

推荐答案

如果你的调用遇到错误,SDK 会抛出一个 ServiceException.此类包含您要查找的属性:

If your call encounters an error, the SDK will throw a ServiceException. This class includes the property you're looking for:

/// <summary>
/// The HTTP status code from the response.
/// </summary>
public System.Net.HttpStatusCode StatusCode { get; }

因此您对 Graph 的调用将类似于:

So your call to Graph would look something like:

public async Task<User> GetUserByIdAsync(string id)
{
    var graphClient = _IUserServiceClient.InitializeGraphClient();

    // Get user by object ID
    try
    {
        return await graphClient
            .Users[id]
            .Request()
            .Select("id,displayName,identities")
            .GetAsync();
    }
    catch (ServiceException)
    {
        throw;
    }
}

你的控制器代码看起来像

And you're Controller code would look something like


[HttpGet("{id}")]
public async Task<IActionResult> GetUserById(string id)
{
    try
    {
        return this.Ok(await _repository.GetUserByIdAsync(id));
    }
    catch (ServiceException ex)
    {
        return this.StatusCode(se.StatusCode);
    }
}

如果您需要通过 HTTP 状态以不同方式处理异常,您也可以这样做

If you need to handle exceptions differently by HTTP Status, you can do that as well

[HttpGet("{id}")]
public async Task<IActionResult> GetUserById(string id)
{
    try
    {
        return this.Ok(await _repository.GetUserByIdAsync(id));
    }
    catch (ServiceException e) when(e.StatusCode == System.Net.HttpStatusCode.NotFound)
    {
        //
        // Do "Not Found" stuff
        //
        return this.StatusCode(e.StatusCode);
    }
    catch (ServiceException e) when(e.StatusCode == System.Net.HttpStatusCode.BadRequest)
    {
        //
        // Do "Bad Request" stuff
        //
        return this.StatusCode(e.StatusCode);
    }
    catch (ServiceException e)
    {
        return this.StatusCode(e.StatusCode);
    }
}

这篇关于Microsoft Graph 错误响应 - 如何从 JSON 中提取 HTTP 状态代码和内部错误代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆