首页 > 解决方案 > 通过 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 获取元数据?

标签: c#odataoffice365api

解决方案


我建议您检查响应的内容,看看它是否提供了任何其他信息。

例如

当服务遇到错误时,它会使用标准的 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按预期从他们的示例中返回模式。


推荐阅读