Post Chiamata di riposo con il token di autenticazione
-
20-12-2019 - |
Domanda
Sto cercando di inviare una richiesta di post a SharePoint Online (sito di autenticazione basata sui reclami) dalla mia applicazione client (applicazione WPF).In questo caso dovrebbe essere un aggiornamento a un listItem per modificare il 'titolo' a 'Test'.
Sto recuperando il cookecontainer tramite msonlineclaimshelper class che mi restituisce con successo un token Auth.
Ma quando provo a inviare la richiesta La risposta è The remote server returned an error: (403) Forbidden.
Webrequest Codice
try
{
var claimshelper = new MsOnlineClaimsHelper(baseUrl, _userName, _password);
var request = (HttpWebRequest)WebRequest.Create(baseUrl + "/" + url);
request.CookieContainer = claimshelper.CookieContainer;
request.Method = "POST";
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("If-Match", "*");
request.Accept = "application/json;odata=verbose";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
}
var webResp = request.GetResponse() as HttpWebResponse;
var theData = new StreamReader(webResp.GetResponseStream(), true);
string payload = theData.ReadToEnd();
}
catch (Exception ex)
{
}
.
URL di riposo:
/_api/lists/getbytitle('SampleList')/items(1)
json payload:
string json = "{ '__metadata': { 'type': 'SP.Data.SampleListListItem' }, 'Title': 'Test'}";
.
Errore:
The remote server returned an error: (403) Forbidden.
Soluzione
Questo errore si verifica dal servizio di riposo di SharePoint 2013 richiede l'utente per includere un valore Request Digest
con ciascun generacolotetagcode, create
e funzionamento update
.Questo valore viene quindi utilizzato da SharePoint per identificare richieste non originali.
Come fornire il valore Digest di richiesta
In delete
(file MsOnlineClaimsHelper class
) Aggiungi il seguente metodo per richiedere il modulo Digest Valore:
/// <summary>
/// Request Form Digest value
/// </summary>
/// <returns></returns>
private string GetFormDigest()
{
var endpoint = "/_api/contextinfo";
var request = (HttpWebRequest) WebRequest.Create(_host.AbsoluteUri + endpoint);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
//request.Accept = "application/json;odata=verbose";
request.ContentLength = 0;
using (var response = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
var result = reader.ReadToEnd();
// parse the ContextInfo response
var resultXml = XDocument.Parse(result);
// get the form digest value
var e = from e in resultXml.Descendants()
where e.Name == XName.Get("FormDigestValue", "http://schemas.microsoft.com/ado/2007/08/dataservices")
select e;
_formDigest = e.First().Value;
}
}
return _formDigest;
}
.
e MsOnlineClaimsHelper.cs
Property:
private string _formDigest;
public string FormDigest
{
get
{
if (_formDigest == null || DateTime.Now > _expires)
{
return GetFormDigest();
}
return _formDigest;
}
}
.
Come eseguire un'operazione di aggiornamento per un listItem utilizzando SharePoint 2013 API di riposo
L'esempio seguente dimostra come eseguire un aggiornamento di una voce di elenco utilizzando l'implementazione fornita per richiedere un modulo digest
Punti chiave:
- .
- L'intestazione
FormDigest
viene utilizzata per specificare il valore del digest modulo - Richiesta
X-RequestDigest
deve essere specificato
Esempio:
var userName = "username@contoso.onmicrosoft.com";
var password = "password";
var payload = "{ '__metadata': { 'type': 'SP.Data.TasksListItem' }, 'Title': 'New Tasl'}"; //for a Task Item
try
{
var claimshelper = new MsOnlineClaimsHelper(baseUrl, _userName, _password);
var request = (HttpWebRequest)WebRequest.Create(baseUrl + "/" + endpointUrl);
request.CookieContainer = claimshelper.CookieContainer;
request.Headers.Add("X-RequestDigest", claimshelper.FormDigest);
request.Method = "POST";
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("If-Match", "*");
request.Accept = "application/json;odata=verbose";
request.ContentType = "application/json;odata=verbose";
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(payload);
writer.Flush();
}
var response = request.GetResponse() as HttpWebResponse;
//...
}
catch (Exception ex)
{
//Error handling goes here..
}
.