Ошибка 403 во время процедуры POST в SharePoint 2013 REST API [на предпосылке] - PullRequest
0 голосов
/ 17 октября 2018

Мне трудно понять, почему я получаю сообщение об ошибке 403 при создании элемента списка с помощью httpclient.Я имею полный контроль над списком, и все же я получаю 403, и это очень расстраивает.Я прошел через очень много решений, но ни одно из них не помогло мне.

Если я создаю HTML-страницу с вызовами ajax к списку, я могу создавать элементы списка из браузера, но тот же код, написанный на c #выдает ошибку 403.

Вот мой тестовый код C #, который выдает 403 с ответом как

{"error":{"code":"-2130575251, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"The security validation for this page is invalid and might be corrupted. Please use your web browser's Back button to try your operation again."}}}

            NetworkCredential cred = new NetworkCredential(username, password);
            HttpClient client = new HttpClient(new HttpClientHandler() { Credentials = cred })
            {
                BaseAddress = new Uri(URL)
            };
            string cmd = "_api/contextinfo";

            client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
            client.DefaultRequestHeaders.Add("ContentType", "application/json");

            StringContent httpContent = new StringContent("");

            var clientresponse = await client.PostAsync(cmd, httpContent);

            if (clientresponse.IsSuccessStatusCode)
            {
                string formdigest = await clientresponse.Content.ReadAsStringAsync();
                JToken t = JToken.Parse(formdigest);
                string digest = t["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
                string[] digestArray = digest.Split(',');

                NetworkCredential cred2 = new NetworkCredential(username, password);
                HttpClient client2 = new HttpClient(new HttpClientHandler() { Credentials = cred2 })
                {
                    BaseAddress = new Uri(URL)
                };
                client2.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
                client2.DefaultRequestHeaders.Add("ContentType", "application/json");
                client2.DefaultRequestHeaders.Add("X-HTTP-Method", "POST");
                client2.DefaultRequestHeaders.Add("X-RequestDigest", digestArray[0].ToString());


                string path = SendShipments.ListPath + "_api/Web/Lists/getbytitle("Test")/items";

                string content_Post = "{__metadata:{'type':'SP.Data.TestListItem'},Title:'Test'}";


                var httpContent_Post = new StringContent(content_Post, Encoding.UTF8, "application/json");

                var clientresponse2 = await client2.PostAsync(path, httpContent_Post);

Вот мой код ajax, который работает как ожидалось

<script>
    $.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('Test')/items",
        type: "POST",
        headers: {
            "accept": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val(),
            "content-Type": "application/json;odata=verbose"
        },
        data: "{__metadata:{'type':'SP.Data.TestListItem'},Title:'Test'}",
        /*where Title is column name and you can add more columns by splitting with ,*/
        success: function (data) {
            console.log(data.d.results);
        },
        error: function (error) {
            alert(JSON.stringify(error));
        }
    });
</script>

Я попытался добавить HttpContext.Current.Items["FormDigestValidated"] = true;, но не сработало.

Пожалуйста, сообщите.Спасибо

1 Ответ

0 голосов
/ 17 октября 2018

Скорее всего, ошибка 403 возникает из-за неверного значения FormDigest.В соответствии с этими строками:

string digest = t["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
string[] digestArray = digest.Split(',');

и

client2.DefaultRequestHeaders.Add("X-RequestDigest", digestArray[0].ToString());

значение дайджеста передается без метка времени , что делает значение дайджеста формы недействительным все свойство FormDigestValue должно быть передано как заголовок X-RequestDigest, как показано ниже:

var formDigest = GetFormDigest(client);

var message = new HttpRequestMessage(HttpMethod.Post, "_api/web/webs/add");
message.Headers.Add("Accept", "application/json;odata=verbose");
message.Headers.Add("X-RequestDigest", formDigest);

где

public static string GetFormDigest(HttpClient client)
{
   var message = new HttpRequestMessage(HttpMethod.Post, "_api/contextinfo");
   message.Headers.Add("Accept", "application/json;odata=verbose");
   var result = client.SendAsync(message).Result;
   result.EnsureSuccessStatusCode();
   var content = result.Content.ReadAsStringAsync().Result;
   var json = JToken.Parse(content);
   var formDigest = json["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
   return formDigest;
}
...