反序列化 OData.Error 条消息
Deserializing OData.Error messages
我有一个使用 Azure AD Graph API 的 ASP.NET 应用程序。通常,当对 Graph API 执行无效操作时,会抛出异常。
以下代码显示了一个会触发异常的无效图形 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 window 的屏幕截图:
我想将此 JSON 转换为 .NET 对象以 return 提供信息性错误详细信息。我正在为此使用 JSON.NET 库,并且我假设 JSON 将反序列化为 ODataError
对象:
var error = Newtonsoft.Json.JsonConvert.DeserializeObject<ODataError>(e.InnerException.Message);
但是,反序列化的对象始终具有 null
的值,这意味着转换没有按预期进行。
也就是说,上面的 JSON 字符串应该映射到什么 class?另外,我是否应该从字符串中删除正斜杠以进行正确的反序列化?
你在反序列化后得到 null 的原因是你的 JSON 对象属性名称不同于 Microsoft.Azure.ActiveDirectory.GraphClient.ODataError
class 属性名称 - "odata.error" 属性 可以未反序列化为错误 属性 of 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));
}
我有一个使用 Azure AD Graph API 的 ASP.NET 应用程序。通常,当对 Graph API 执行无效操作时,会抛出异常。
以下代码显示了一个会触发异常的无效图形 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 window 的屏幕截图:
我想将此 JSON 转换为 .NET 对象以 return 提供信息性错误详细信息。我正在为此使用 JSON.NET 库,并且我假设 JSON 将反序列化为 ODataError
对象:
var error = Newtonsoft.Json.JsonConvert.DeserializeObject<ODataError>(e.InnerException.Message);
但是,反序列化的对象始终具有 null
的值,这意味着转换没有按预期进行。
也就是说,上面的 JSON 字符串应该映射到什么 class?另外,我是否应该从字符串中删除正斜杠以进行正确的反序列化?
你在反序列化后得到 null 的原因是你的 JSON 对象属性名称不同于 Microsoft.Azure.ActiveDirectory.GraphClient.ODataError
class 属性名称 - "odata.error" 属性 可以未反序列化为错误 属性 of 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));
}