【问题标题】:Deserializing OData.Error messages反序列化 OData.Error 消息
【发布时间】:2015-10-05 08:11:11
【问题描述】:

我有一个使用 Azure AD Graph API 的 ASP.NET 应用程序。通常,当对 Graph API 执行无效操作时,会引发异常。

以下代码显示了会触发异常的无效 Graph API 调用:

// Query the Azure AD User
var userToUpdate = await activeDirectoryClient.Users.GetByObjectId("user@domain.net").ExecuteAsync();

// Set given name to an empty string (not allowed)
userToUpdate.GivenName = "";

try
{
    // Update the user in Azure AD
    await userToUpdate.UpdateAsync();
}
catch (Exception e)
{
    // Return exception message
}

内部异常的消息是一个 JSON 字符串,每个引号前都有正斜杠。它看起来像这样:

"{\"odata.error\":{\"code\":\"Request_BadRequest\",\"message\":{\"lang\":\"en\",\"value\":\"Invalid value specified for property 'givenName' of resource 'User'.\"},\"values\":[{\"item\":\"PropertyName\",\"value\":\"givenName\"},{\"item\":\"PropertyErrorCode\",\"value\":\"InvalidValue\"}]}}"

附上发现异常消息的 Locals 窗口的屏幕截图:

我想将此 JSON 转换为 .NET 对象以返回信息丰富的错误详细信息。我为此使用 JSON.NET 库,并假设 JSON 将反序列化为 ODataError 对象:

var error = Newtonsoft.Json.JsonConvert.DeserializeObject<ODataError>(e.InnerException.Message);

但是,反序列化对象的值始终为null,这意味着转换未按预期进行。

话虽如此,上面的 JSON 字符串应该映射到什么类?另外,我应该从字符串中删除正斜杠以进行正确的反序列化吗?

【问题讨论】:

  • 你想做什么?您如何进行 OData 调用以及您使用什么客户端?异常的类型是什么? ODataErrorException 已经有一个带有反序列化错误的 Error 属性。在任何其他情况下,异常消息将包含您的客户端生成的特定消息(可能在反序列化任何特定错误消息之后),而不是原始 Json 部分。您需要阅读响应以获取原始 json
  • 嗨@PanagiotisKanavos,感谢您的评论。我已经用更多的代码示例更新了这个问题,我希望我能澄清我想要完成的事情。如果我需要进一步解释它的任何部分,请告诉我。
  • 你还没解释——抛出的异常是什么类型的?如果是 ODataErrorException,则无需执行任何操作,只需捕获正确的异常类型即可。至于原始的 Json,你不会在异常对象中找到它。
  • 对不起,异常类型为System.Data.Services.Client.DataServiceRequestException,其内部异常类型为System.Data.Services.Client.DataServiceClientException。问题中的 JSON 字符串是 InnerException 的消息。这就是为什么我很难确定将字符串转换为哪种类型的异常。

标签: c# json json.net odata azure-ad-graph-api


【解决方案1】:

反序列化后得到 null 的原因是您的 JSON 对象属性名称与 Microsoft.Azure.ActiveDirectory.GraphClient.ODataError 类属性名称不同 - “odata.error”属性无法反序列化为 Microsoft.Azure.ActiveDirectory.GraphClient.ODataError 的错误属性

作为解决方法,我添加了自己的类型以进行正确的反序列化:

internal class ODataError
    {
        [JsonProperty("odata.error")]
        public ODataErrorCodeMessage Error { get; set; }
    }

    internal class ODataErrorCodeMessage
    {
        public string Code { get; set; }

        public ODataErrorMessage Message { get; set; }

        public List<ExtendedErrorValue> Values { get; set; }
    }

    internal class ExtendedErrorValue
    {
        public string Item { get; set; }

        public string Value { get; set; }
    }

    internal class ODataErrorMessage
    {
        public string Lang { get; set; }

        public string Value { get; set; }
    }

正确反序列化该 JSON 消息后:

...
    try
    {
        await ADClient.Users.AddUserAsync(newUser);
        return Result.Ok();
    }
    catch (DataServiceRequestException ex)
    {
        var innerException = ex.InnerException;
        var error = JsonConvert.DeserializeObject<ODataError>(innerException.Message);
        return Result.Fail(new Error(error.Error.Message.Value, error.Error.Code, ex));
    }

【讨论】:

  • 您是否仍需要创建自己的反序列化类型或 Microsoft 对此进行了更新?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 2012-05-16
  • 1970-01-01
  • 2014-07-08
  • 2011-09-09
  • 1970-01-01
相关资源
最近更新 更多