【问题标题】:Get Title of SharePoint Site from Console App从控制台应用程序获取 SharePoint 网站的标题
【发布时间】:2018-11-19 06:58:06
【问题描述】:

我有一个用 C# 编写的控制台应用程序。我需要从 SharePoint 网站获取一些信息。此 SharePoint 实例是 Office 365(即 SharePoint Online)的一部分。

我的挑战是,我不能使用辅助库。因为我使用的是 .NET Core,所以我必须使用基于 REST 的 API。

首先,我在 Azure Active Directory 中注册了我的控制台应用程序。此控制台应用是在我的 Office 365 环境所属的同一 Azure Active Directory 中创建的。我还向我的控制台应用程序授予了“Office 365 SharePoint Online”API 的“读取所有网站集中的项目”委派权限。

在我的情况下,我有一个控制台应用程序位于服务器上。我在我的 SharePoint 租户上设置了一个具有用户名/密码的测试用户。我还拥有在 Azure Active Directory 中注册的控制台应用程序的客户端 ID 和重定向 URL。

此时,我有一些代码如下所示:

var accessToken = await GetToken(); // retrieves a token from Active Directory
using(var client = new HttpClient()) {
    client
        .DefaultRequestHeaders
        .Clear();

    client
        .DefaultRequestHeaders
        .Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    client
        .DefaultRequestHeaders
        .Accept
        .Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var apiUrl = "https://[mySite].sharepoint.com/_api/web";

    // how do I get the title of the site at the apiUrl variable?
}

我觉得我很接近了,因为我得到了一个访问令牌。我似乎无法弄清楚如何获得该网站的标题。如何从我的 C# 代码中获取 SharePoint 网站的标题?

【问题讨论】:

  • 下面有一些不错的答案,您能否向我们提供您用于实际获取令牌的代码?根据应用注册的类型,您可能需要一些其他方式来获取令牌。顺便说一句,微软现在到处都在使用 JWT 令牌,它们包含有关它们有效用途的信息。只需将它们粘贴到jwt.io

标签: c# sharepoint sharepoint-online


【解决方案1】:

刚刚意识到您使用的是 SharePoint API 而不是 Graph API,但它仍然可能对您有用!

这是 JSON 设置,你不需要它,但它会使反序列化更容易

public class SharePointSiteObject
{
    [JsonProperty("createdDateTime")]
    public string CreatedDate { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("id")]
    public string ID { get; set; }

    [JsonProperty("lastModifiedDateTime")]
    public string LastModified { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("webUrl")]
    public string WebUrl { get; set; }

    [JsonProperty("displayName")]
    public string DisplayName { get; set; }

    [JsonProperty("createdBy")]
    public user CreatedBy { get; set; }

    [JsonProperty("lastModifiedBy")]
    public user ModifiedBy { get; set; }
}

反序列化返回的 JSON 的代码

public static SharePointSiteObject SharePointDeserialize(string jObject)
{
    SharePointSiteObject sharePointSite;

    sharePointSite = JsonConvert.DeserializeObject<SharePointSiteObject>(jObject);

    return sharePointSite;
}

查询 Graph API、向其提供端点和令牌的通用方法

public static async Task<string> Run(string url, string token)
{

    var httpClient = new HttpClient();
    HttpResponseMessage response;
    try {
        var request = new HttpRequestMessage(HttpMethod.Get, url);
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
        response = await httpClient.SendAsync(request);
        var content = await response.Content.ReadAsStringAsync();
        return content;
    }
    catch (Exception ex) {
        return ex.ToString();
    }
}

在您要调用图形 API 的地方使用以下代码并显示 SharePoint 网站名称

string url = "https://graph.microsoft.com/v1.0/sites/" + sharePointID;
string token = await GetToken();
var request = await Run(url, token);
var result = SharePointDeserialize(request);
Console.WriteLine(result.DisplayName);

你应该试试 MS Graph Explorer,它非常有用:https://developer.microsoft.com/en-us/graph/graph-explorer

【讨论】:

  • 感谢您的回复。我尝试使用您的方法,但是,我收到“未经授权”错误。这让我觉得我没有正确的令牌。我确实有一个从https://login.microsoftonline.com/ 获得的令牌。我需要做更多的事情来获得特定的令牌吗?
  • 试试developer.microsoft.com/en-us/graph/docs/concepts/get-started,如果你使用的是WPF,这里有一个很好的例子github.com/Azure-Samples/…。如果你能展示你的代码,那一切都失败了。
  • 我查看了代码。但是,这些示例要求用户通过 OAuth 提示输入他们的凭据。我的挑战是,我有一个分配给我的应用程序的用户名和密码。我想通过这些凭据与 SharePoint 凭据进行交互。如果我已经有用户名/密码,如何进行身份验证?
  • 微软没有发布如何通过用户名/密码进行身份验证的示例,这是可能的,但我没有任何代码。无论如何,Marc LaFleur 的回答似乎更适合您的问题
【解决方案2】:

SharePoint REST API 的 web resource 包含一个 Title 属性,该属性表示网站的标题。

调用:

GET http://<site url>/_api/web/title

返回:

<d:Title xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 
    xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 
    xmlns:georss="http://www.georss.org/georss" 
    xmlns:gml="http://www.opengis.net/gml">Site Title Goes Here</d:Title>

或者,假设您已将 Accept 标头设置为 application/json

{
  "odata.metadata": 
  "https://microsoft.sharepoint.com/sites/msw/_api/$metadata#Edm.String",
  "value": "MSW"
}

【讨论】:

  • 认证过程是什么?目前,我正在从 Azure Active Directory 获取 OAuth 令牌。但是,我仍然收到 401。
  • 如果您使用的是 v1 Endpoint,则可以在 Azure AD 门户的应用注册屏幕中找到 SharePoint 的范围。你还需要将 Resource 更改为 SharePoint 租户的 URI(而不是 https://graph.microsoft.com 用于 Microsoft Grap)。
  • 一些 server-2-server 流程​​要求您使用证书而不是密钥进行身份验证。它还有助于复制令牌(这是一个 JWT)并将其粘贴到 jwt.io 上,如果它具有正确的属性,它看起来会有所不同。
【解决方案3】:

SharePoint 终结点遵循 OData 约定。

因此,您可以使用$select 查询选项来为给定的网络或列表或字段等指定所需的数据。

因此,在您的情况下,您可以简单地修改您的端点,如下所示:

var apiUrl = "https://[mySite].sharepoint.com/_api/web?$select=Title";

如果您想获取描述、徽标、Web 模板等其他属性,您可以将其附加为:

var apiUrl = "https://[mySite].sharepoint.com/_api/web?$select=Title,Description,
SiteLogoUrl,WebTemplate";

参考 - List of properties in SPO - Web object

另外,请确保您在Office 365 SharePoint Online 权限中检查了Have full control of all site collections 权限,如下所示:

我正在使用的代码的完整版本:

1) 创建AuthenticationResponse.cs 类:

public class AuthenticationResponse
{
        public string token_type { get; set; }
        public string scope { get; set; }
        public int expires_in { get; set; }
        public int expires_on { get; set; }
        public int not_before { get; set; }
        public string resource { get; set; }
        public string access_token { get; set; }
        public string refresh_token { get; set; }
        public string id_token { get; set; }
}

2) 在您的代码中使用它,如下所示:

string userName = "user@tenantName.onmicrosoft.com";
string password = "password";

List<KeyValuePair<string, string>> vals = new List<KeyValuePair<string, string>>();

string tenantName = "tenantName.OnMicrosoft.com";
string authString = "https://login.microsoftonline.com/" + tenantName;
string resource = "https://graph.microsoft.com";

AuthenticationContext authenticationContext = new AuthenticationContext(authString, false);

string clientId = "<client-id>";
string key = "<client-secret>";

vals.Add(new KeyValuePair<string, string>("client_id", clientId));
vals.Add(new KeyValuePair<string, string>("resource", resource));
vals.Add(new KeyValuePair<string, string>("username", userName));
vals.Add(new KeyValuePair<string, string>("password", password));
vals.Add(new KeyValuePair<string, string>("grant_type", "password"));
vals.Add(new KeyValuePair<string, string>("client_secret", key));

string url = string.Format("https://login.windows.net/{0}/oauth2/token", tenantName);

using (HttpClient httpClient = new HttpClient())
{
    httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
    HttpContent content = new FormUrlEncodedContent(vals);
    HttpResponseMessage hrm = httpClient.PostAsync(url, content).Result;

    AuthenticationResponse authenticationResponse = null;
    if (hrm.IsSuccessStatusCode)
    {
        Stream data = await hrm.Content.ReadAsStreamAsync();
        DataContractJsonSerializer serializer = new
        DataContractJsonSerializer(typeof(AuthenticationResponse));
        authenticationResponse = (AuthenticationResponse)serializer.ReadObject(data);

        var accessToken = authenticationResponse.access_token;

        httpClient
        .DefaultRequestHeaders
        .Clear();

        httpClient
            .DefaultRequestHeaders
            .Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

        httpClient
            .DefaultRequestHeaders
            .Accept
            .Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var apiUrl = "https://[mySite].sharepoint.com/_api/web?$select=Title";      

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    相关资源
    最近更新 更多