I have created a plugin in Dynamics CRM online 2015 that creates folders in a SharePoint Online Document Library. The plugin works fine. I want, however, to rename the folders in the Document Library when an Account's name in CRM changes.
Since both the CRM and SharePoint are online, I can't use Microsoft.SharePoint.Client.dll so I have used SPOAuthUtility Class based on the following articles
https://www.develop1.net/public/post/SharePoint-Integration-Reloaded-e28093-Part-3.aspx
The code for creating folders works fine and I use the following code to rename the folders upon the change of the Account name in CRM:
string restFolderQuery = "_api/web/getfolderbyserverrelativeurl('" +
rootFolderName + "/" + oldName + "')/ListItemAllFields";
Uri url = new Uri(String.Format("{0}/{1}", webSiteUrl, restFolderQuery));
byte[] result = HTTPHelper.SendODataJsonRequest(
url,
"POST", // setting data to SP through the rest api usually uses the POST verb
Encoding.UTF8.GetBytes("{ '__metadata':{ 'type': 'SP.Data.AccountItem' },
'FileLeafRef': '" + newName + "' ,'Title:': '" + newName + "' }"),
(HttpWebRequest)HttpWebRequest.Create(url),
SpoAuthUtility.Current, // pass in the helper object that allows us to make authenticated calls to SPO rest services
new Dictionary<string, string>() {
{"IF-MATCH", "*"}, {"X-HTTP-Method", "MERGE" }
}
);
This will call the SendODataJsonRequest function in the HTTPHelper class:
public static byte[] SendODataJsonRequest(Uri uri, String method, byte[] requestContent, HttpWebRequest clientHandler, SpoAuthUtility authUtility, Dictionary<string, string> headers = null)
{
if (clientHandler.CookieContainer == null)
clientHandler.CookieContainer = new CookieContainer();
CookieContainer cookieContainer = authUtility.GetCookieContainer(); // get the auth cookies from SPO after authenticating with Microsoft Online Services STS
foreach (Cookie c in cookieContainer.GetCookies(uri))
{
clientHandler.CookieContainer.Add(uri, c); // apppend SPO auth cookies to the request
}
// string digest = SpoAuthUtility.GetRequestDigest();
Dictionary<string, string> _dic = new Dictionary<string, string>();
_dic.Add("Authorization", "Bearer" + cookieContainer.GetCookieHeader(uri));
return SendHttpRequest(
uri,
method,//digest,
requestContent,
"application/json;odata=verbose;charset=utf-8", // the http content type for the JSON flavor of SP REST services
clientHandler,
_dic);
}
Which in turn calls the SendHttpRequest function:
public static byte[] SendHttpRequest(Uri uri, String method, byte[] requestContent = null, string contentType = null, HttpWebRequest clientHandler = null, Dictionary<string, string> headers = null)
{
try
{
HttpWebRequest request = clientHandler == null ? (HttpWebRequest)HttpWebRequest.Create(uri) : clientHandler;
byte[] responseStream;
request.Method = method;
request.Accept = contentType;
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"; // This must be here as you will receive 403 otherwise
request.AllowAutoRedirect = false; // This is key, otherwise it will redirect to failed login SP page
// append additional headers to the request
if (headers != null)
{
foreach (var header in headers)
{
if (request.Headers.AllKeys.Contains(header.Key))
{
request.Headers.Remove(header.Key);
}
request.Headers.Add(header.Key, header.Value);
}
}
if (requestContent != null && (method == "POST" || method == "PUT" || method == "DELETE"))
{
if (!string.IsNullOrEmpty(contentType))
{
request.ContentType = contentType; // if the request has a body set the MIME type
}
request.ContentLength = requestContent.Length;
using (Stream s = request.GetRequestStream())
{
s.Write(requestContent, 0, requestContent.Length);
s.Close();
}
}
// Not using Using here as you may still like to access the reponse outside of this method
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8"));
responseStream = Encoding.UTF8.GetBytes(sr.ReadToEnd());
return responseStream;
}
catch (Exception ex)
{
throw;
}
}
The same code works fine in a Console App with the credentials provided and it does rename the specified folder, but it doesn't work in the CRM plugin
It seems like there is something wrong with the HTTPRequest this code creates since I get an error response from the server: The remote server returned an error (400) bad request
Can anyone help me with the code to rename a SharePoint folder from a Dynamic CRM plugin