反序列化OData.Error消息

时间:2015-10-05 08:11:12

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

我有一个使用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窗口的屏幕截图: Exception details

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

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

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

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

1 个答案:

答案 0 :(得分:8)

反序列化后您获得null的原因是您的JSON对象属性名称与Microsoft.Azure.ActiveDirectory.GraphClient.ODataError类属性名称不同 - &#34; odata.error&#34;属性无法反序列化为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));
    }