c# - 通过 odata.context Url 获取 Office 365 服务通信 API 的元数据
问题描述
我正在尝试从 Office 365 管理 API 获取元数据。当我拨打以下网址时
resource = "https://manage.office.com/api/v1.0/tenant-id/ServiceComms/Messages"
我收到响应,在内容中,我有以下信息(我已将租户 GUID 替换为名称):
{
"@odata.context": "https://office365servicecomms-prod.cloudapp.net/api/v1.0/tenant-id/$metadata#Messages",
"value": [
{
"@odata.type": "#Microsoft.Office365ServiceComms.ExposedContracts.Message",
"@odata.id": "https://office365servicecomms-prod.cloudapp.net/api/v1.0/tenant-id/Messages('LY177449')",
"@odata.editLink": "https://office365servicecomms-prod.cloudapp.net/api/v1.0/tenant-id/Messages('LY177449')",
"AffectedWorkloadDisplayNames@odata.type": "#Collection(String)",
"AffectedWorkloadDisplayNames": [],
"AffectedWorkloadNames@odata.type": "#Collection(String)",
"AffectedWorkloadNames": [
从响应中,我假设我可以从中检索元数据https://office365servicecomms-prod.cloudapp.net/api/v1.0/tenant-id/$metadata
但是当我对该网址进行身份验证调用时,我只会收到内部服务器错误消息
string resource =
"https://office365servicecomms-prod.cloudapp.net/api/v1.0/tenant-id/$metadata";
using(HttpClient httpClient = new HttpClient())
{
httpClient.Timeout = new TimeSpan(0, 2, 0);
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", _authResult.AccessToken);
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
HttpResponseMessage response = await httpClient.GetAsync(resource);
}
在httpClient
,我有 2 个标题,Authorization: bearer token
(工作正常)和Accept: application/json
在HttpResponseMessage response
中,我得到一个500 Internal Server Error
. 没有其他信息。
我不明白我在这里做错了什么。有谁知道如何从 Office 365 服务通信 API 获取元数据?
解决方案
我建议您检查响应的内容,看看它是否提供了任何其他信息。
例如
当服务遇到错误时,它会使用标准的 HTTP 错误代码语法向调用者报告错误响应代码。根据 OData V4 规范,附加信息作为单个 JSON 对象包含在失败调用的正文中。以下是完整 JSON 错误正文的示例:
{
"error":{
"code":"AF5000. An internal server error occurred.",
"message": "Retry the request."
}
}
参考Office 365 服务通信 API 参考(预览版):错误
当我测试您的示例网址时
https://office365servicecomms-prod.cloudapp.net/api/v1.0/tenant-id/$metadata#CurrentStatus
我得到一个空引用异常
System.NullReferenceException: Object reference not set to an instance of an object.
at Autofac.Integration.WebApi.AutofacWebApiFilterProvider.GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.<ReverseIterator>d__75`1.MoveNext()
at System.Web.Http.Controllers.HttpActionDescriptor.<RemoveDuplicates>d__3.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.<ReverseIterator>d__75`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at System.Web.Http.Controllers.HttpActionDescriptor.InitializeFilterPipeline()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at System.Web.Http.Controllers.HttpActionDescriptor.GetFilterGrouping()
at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Office365ServiceComms.MessageHandlers.RequestResponseLogHandler.<SendAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()
这是意料之中的,因为我没有租户 ID 或身份验证令牌。
而且由于此 API 处于预览状态,因此很可能是他们方面的实际问题/错误。如果他们有这种能力,应该考虑提出问题。
当我在 odata.org 测试 odata 示例时,调用会odata.context
按预期从他们的示例中返回模式。
推荐阅读
- apache-kafka-streams - 序列化程序与实际的键类型不兼容(键类型:java.lang.String)
- android - 成功登录Android Firebase无密码身份验证后如何关闭AuthUI
- unit-testing - Mstest [ClassCleanup] 在 VS 2019 中根本没有执行
- c++ - 指针后面的值通过打印来改变
- java - 在 Apache Poi Java 中编写 Excel 时如何将科学值转换为数值
- django-views - 我们计算的请求签名与您提供的签名不匹配
- php - 将 PHP 7.3.1 更新为 PHP 7.3.5
- python - 带有多个数组的 Python zip
- flutter - Flutter : Facebook 受众网络横幅 error_message: No Fill, error_code: 1001 当回到上一个路由时
- c - msp430 定时器中断和端口中断