I try to create folder in sharepoint online, based on some of tutorial. the problem comes since creating folder is not given "Title" column value.
I want to create folder and also update column "Title".
here is the code for create folder
public string CreateDocumentLibrary(string siteUrl, string relativePath)
{
//bool responseResult = false;
string resultUpdate = string.Empty;
string responseResult = string.Empty;
if (siteUrl != _siteUrl)
{
_siteUrl = siteUrl;
Uri spSite = new Uri(siteUrl);
_spo = SpoAuthUtility.Create(spSite, _username, WebUtility.HtmlEncode(_password), false);
}
string odataQuery = "_api/web/folders";
byte[] content = ASCIIEncoding.ASCII.GetBytes(#"{ '__metadata': { 'type': 'SP.Folder' }, 'ServerRelativeUrl': '" + relativePath + "'}");
string digest = _spo.GetRequestDigest();
Uri url = new Uri(String.Format("{0}/{1}", _spo.SiteUrl, odataQuery));
// Set X-RequestDigest
var webRequest = (HttpWebRequest)HttpWebRequest.Create(url);
webRequest.Headers.Add("X-RequestDigest", digest);
// Send a json odata request to SPO rest services to fetch all list items for the list.
byte[] result = HttpHelper.SendODataJsonRequest(
url,
"POST", // reading data from SP through the rest api usually uses the GET verb
content,
webRequest,
_spo // pass in the helper object that allows us to make authenticated calls to SPO rest services
);
string response = Encoding.UTF8.GetString(result, 0, result.Length);
if (response != null)
{
//responseResult = true;
responseResult = response;
}
return responseResult;
}
I already tried to use CAML, but, the problem is, the list of sharepoint is big, so got the error prohibited access related to limit tresshold.
Please help.
Refer below code to update folder name.
function renameFolder(webUrl,listTitle,itemId,name)
{
var itemUrl = webUrl + "/_api/Web/Lists/GetByTitle('" + listTitle + "')/Items(" + itemId + ")";
var itemPayload = {};
itemPayload['__metadata'] = {'type': getItemTypeForListName(listTitle)};
itemPayload['Title'] = name;
itemPayload['FileLeafRef'] = name;
var additionalHeaders = {};
additionalHeaders["X-HTTP-Method"] = "MERGE";
additionalHeaders["If-Match"] = "*";
return executeJson(itemUrl,"POST",additionalHeaders,itemPayload);
}
function getItemTypeForListName(name) {
return"SP.Data." + name.charAt(0).toUpperCase() + name.slice(1) + "ListItem";
}
Related
I have an http-triggered azure function that receives a zip code. It then queries an Azure Table using the table API and retrieves the city, state, etc. The table contains zip/postal codes for US and CAN so there's about a million rows. When I send a request it returns the correct value the first time but if I keep sending it over and over it randomly switches between returning the record and returning an empty set. So it's not failing, and I'm not getting any kind of error like a timeout.
here is an example of a successful reply:
{
odata.metadata: "https://storageaccount###.table.core.windows.net/$metadata#Table###",
value: [
{
odata.etag: "W/"datetime'2019-10-18T16%3A02%3A26.9420514Z'"",
PartitionKey: "Portsmouth",
RowKey: "00210",
Timestamp: "2019-10-18T16:02:26.9420514Z",
AreaCode: "603",
City: "Portsmouth",
Country: "US",
Pref: "P",
State: "NH",
Zip: "00210"
}
]
}
and here is an empty one after pressing F5 after getting above reply:
{
odata.metadata: "https://storageaccount###.table.core.windows.net/$metadata#Table###",
value: [ ]
}
And then if I keep pressing F5 sometimes I get the record and sometimes I don't.
here are the table api url parameters (SAS-minus the signature)
?$filter=RowKey eq '00210' and Country eq 'US'
&sv=2019-02-02
&ss=t
&srt=sco
&sp=r
&se=2099-10-18T05:27:30Z
&st=2019-10-17T21:27:30Z
&spr=https
Does anyone know why it's behaving this way or what I could look into to figure it out?
According to this page there is a 5 second timeout for querying azure tables
(https://learn.microsoft.com/en-us/rest/api/storageservices/query-timeout-and-pagination). but when I look at the headers in postman I don't see any tokens.
postman results: https://i.stack.imgur.com/hReDM.png
full CORRECTED code
public static async Task<string> Run(HttpRequest req, ILogger log)
{
log.LogInformation("Start time = "+ DateTime.Now);
string apiResponse = "";
string zip = req.Query["zip"];
if(string.IsNullOrEmpty(zip)){return "No zip code found - please provide a url parameter in the format 'zip=[code]'";}
string apiBaseUrl = "https://***storage.table.core.windows.net/zip**?";
string queryFilter = "$first&$filter=RowKey eq '" + zip + "'";
//generate auth url in storage account in Azure
string authorization = "&sv=2019-02-02&ss=t&srt=sco&sp=r&se=2099-10-18T00:38:11Z&st=2019-10-17T16:38:11Z&spr=https&sig=7S%2BkaiTwGsZIkL***";
Regex rx_US = new Regex(#"^\d{5}$");
Regex rx_CA = new Regex(#"^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$");
if (rx_US.IsMatch(zip))
{
queryFilter = queryFilter + " and Country eq 'US'";
}
else if (rx_CA.IsMatch(zip))
{
//the table search is case sensitive - test for common errors
zip = zip.ToUpper(); //make all upper case
Regex rx_CA1 = new Regex(#"^[A-Z]\d[A-Z]-\d[A-Z]\d$"); //dash
Regex rx_CA2 = new Regex(#"^[A-Z]\d[A-Z]\d[A-Z]\d$"); //no space
if (rx_CA1.IsMatch(zip)){zip = zip.Replace("-", " ");}
if (rx_CA2.IsMatch(zip)){zip = zip.Insert (3, " ");}
queryFilter = "$single&$filter=RowKey eq '" + zip + "'" + " and Country eq 'CA'";
}
string queryUrl = apiBaseUrl + queryFilter + authorization;
try
{
var httpWebRequest = WebRequest.Create(queryUrl);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("Accept","application/json"); //if this is omitted you will get xml format
httpWebRequest.Method = "GET";
var httpResponse = await httpWebRequest.GetResponseAsync();
using(var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
apiResponse = responseText;
log.LogInformation("Full Table Response = " + responseText);
}
int i = 0;
while (httpResponse.Headers["x-ms-continuation-NextPartitionKey"] != null && apiResponse.Length < 105)
{
//if response is > 105 then it found something - don't keep looking
//if there are continuation tokens then keep querying until you find something
var partitionToken = httpResponse.Headers["x-ms-continuation-NextPartitionKey"];
var rowToken = httpResponse.Headers["x-ms-continuation-NextRowKey"];
var continuationUrl = "NextPartitionKey="+partitionToken+"&NextRowKey="+rowToken+"&";
queryUrl = apiBaseUrl + continuationUrl + queryFilter + authorization;
log.LogInformation("begin new httpRequest...");
httpWebRequest = WebRequest.Create(queryUrl);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add("Accept","application/json");
httpWebRequest.Method = "GET";
httpResponse = await httpWebRequest.GetResponseAsync();
using(var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
apiResponse = responseText;
log.LogInformation("Full Table Response = " + responseText);
}
i++;
log.LogInformation("loop # "+ i + " - url = " + queryUrl + " Response = "+ apiResponse);
}
if(apiResponse.Length > 105)
{
//strip out extra data
apiResponse = apiResponse.Remove(1,101);
apiResponse = apiResponse.Remove(apiResponse.Length - 2,2);
}
else
{
apiResponse = "No data found for zip = " + zip + " - Ensure you have proper format and case";
}
}
catch (Exception ex)
{
apiResponse = "error: " + ex.Message;
}
log.LogInformation("ZipPostal function completed and returned "+ apiResponse);
return apiResponse;
}
New to MVC and having some trouble with what should be simple. I'm trying to return a dataset to just an Excel spreadsheet without any real UI.
Here's my code (cannibalized from a few sources):
Controller code:
public ActionResult GetCommissionsExcel(string agencyid, string month, string year)
{
try
{
var as400rep = new iSeriesRepository(new iSeriesContext());
var results = as400rep.GetCommissionExcel(agencyid, month, year);
string xml = String.Empty;
XmlDocument xmlDoc = new XmlDocument();
XmlSerializer xmlSerializer = new XmlSerializer(results.GetType());
using (System.IO.MemoryStream xmlStream = new System.IO.MemoryStream())
{
xmlSerializer.Serialize(xmlStream, results);
xmlStream.Position = 0;
xmlDoc.Load(xmlStream);
xml = xmlDoc.InnerXml;
}
var fName = string.Format("CommissionsExcelExport-{0}", DateTime.Now.ToString("s"));
byte[] fileContents = System.Text.Encoding.UTF8.GetBytes(xml);
return File(fileContents, "application/vnd.ms-excel", fName);
}
catch (Exception ex)
{
Log.Error(ex.Message, ex.InnerException);
throw;
}
}
The jQuery call:
function getExcelExport() {
var activePane = $('div.tab-pane.active');
var agencyCompany = $(activePane).find('#Agency_AgencyId').val();
var month = $(activePane).find('#CommissionMonth').val();
var year = $(activePane).find('#CommissionYear').val();
var url = '#Url.Content("~")' + 'AgencyManagement/GetCommissionsExcel';
window.location = 'AgencyManagement/GetCommissionsExcel';
//$.post('#Url.Action("GetCommissionsExcel", "AgencyManagement")' , {agencyid: agencyCompany, month: month, year: year});
};
It pulls back the data, but I can't figure out how to get it to pop from the search window. It looks like the window.location line makes the call, but I need to post the parameters to the call and that's where I'm stuck.
Figured it out. Just needed to call the jQuery as follows:
window.location = 'AgencyManagement/GetCommissionsExcel?agencyID=' + agencyCompany + '&month=' + month + '&year=' + year;
And I needed to append ".xls" to the filename in the controller action.
var fName = string.Format("CommissionsExcelExport-{0}", DateTime.Now.ToString("s"));
fName = fName + ".xls";
Worked like a charm
This is my first foray into Google Analytics. I created a service account and downloaded the p12 file from the developer console.
This code works, but in an incomplete way.
I have two accounts, but the code below just returns one account from the list.
How do I get all my accounts listed?
private static ServiceAccountCredential Run2()
{
const string keyfilePath = "file.p12";
const string serviceAccountMail = "notarealemailaddress#developer.gserviceaccount.com";
var certificate = new X509Certificate2(keyfilePath, "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountMail)
{
Scopes = new[] { AnalyticsService.Scope.Analytics, AnalyticsService.Scope.AnalyticsReadonly, AnalyticsService.Scope.AnalyticsProvision }
}.FromCertificate(certificate));
return credential;
}
static void Main()
{
var cr = Run2();
var service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = cr,
ApplicationName = "Analytics API Sample"
});
var request = service.Management.Accounts.List();
request.MaxResults = 20;
var result = request.Execute();
foreach (var item in result.Items)
{
Console.WriteLine("Account Name: {0} {1} {2}", item.Name, item.Kind, item.Id);
}
}
This is what I ended up doing. The service account that Google creates needs to be added to every account that you need to access. I figured this from reading the documentation.
https://developers.google.com/analytics/devguides/config/mgmt/v3/quickstart/service-py
Try this out
ManagementResource.AccountSummariesResource.ListRequest list = service.Management.AccountSummaries.List();
list.MaxResults = 1000; // Maximum number of Account Summaries to return per request.
AccountSummaries feed = list.Execute();
List allRows = new List();
//// Loop through until we arrive at an empty page
while (feed.Items != null)
{
allRows.AddRange(feed.Items);
// We will know we are on the last page when the next page token is
// null.
// If this is the case, break.
if (feed.NextLink == null)
{
break;
}
// Prepare the next page of results
list.StartIndex = feed.StartIndex + list.MaxResults;
// Execute and process the next page request
feed = list.Execute();
}
feed.Items = allRows;
//Get account summary and display them.
foreach (AccountSummary account in feed.Items)
{
// Account
Console.WriteLine("Account: " + account.Name + "(" + account.Id + ")");
foreach (WebPropertySummary wp in account.WebProperties)
{
// Web Properties within that account
Console.WriteLine("\tWeb Property: " + wp.Name + "(" + wp.Id + ")");
//Don't forget to check its not null. Believe it or not it could be.
if (wp.Profiles != null)
{
foreach (ProfileSummary profile in wp.Profiles)
{
// Profiles with in that web property.
Console.WriteLine("\t\tProfile: " + profile.Name + "(" + profile.Id + ")");
}
}
}
}
Reference: http://www.daimto.com/googleanalytics-management-csharp/
http://www.daimto.com/googleAnalytics-authentication-csharp/
I am new to CRM and have been able to figure out everything up to now. I have read so many post and internet post and tried them. I have watched some many videos. It seems it should be easy. The contact record has the ParentCustomerID, and ParentCustomerName that holds the account if there is one associated. Now I am just totally confused on the required steps.
Requirement: - I need Account Name to be displayed on the contact level phone call form and saved in phone call table so that it can be visible in the phone call view.
I have in Phone Call N:1 Relationship field str_companyid (lookup) primary Entity is Account with Referential behavior.
I tried a Phone Call N:1 Relationship field new_companystring (lookup) primary Entity is Contact with Referential behavior. I came to the conclusion that this is not a valid approach. Let me know if incorrect.
Do I need a N:N instead?
I have added the str_companyid field to the form. I went to the "Create a phone call for a contact" workflow process. On the "Create PhoneCall" step I have added the dynamic field {Company(Contact)}. After save and publishes; I created a phone call and it isn't populated.
I have tried different Web Resource JS. I have added the JS in the onload of the form properties.
Why doesn't something as easy as this work? I can't seem to get the retrieveRecord to work. I have also tried the xmlHttpObject object but it returns 0.
Can someone help assist me on what I am missing? What are the complete steps to accomplish this?
![I have screenshots below and the code I was running][1]
function PopulateCompanyName()
{
//get group GUID
if (Xrm.Page.getAttribute("to").getValue()[0].id != null) {
var lookup = Xrm.Page.getAttribute("to").getValue();
alert(lookup[0].id);
alert(lookup[0].typename);
alert(lookup[0].name);
alert(lookup);
SDK.JQuery.retrieveRecord(lookup[0].id,
lookup[0].typename,
"ParentCustomerID",
null,
function (lookup) {
Xrm.Page.getAttribute("Company").setValue(lookup[0].str_companyid);
});
}
else {
Xrm.Page.getAttribute("str_companyid").setValue(null);
}
}
function GetCompany()
///Get lookup ID
{
alert("I am Here");
var lookupfield = Xrm.Page.getAttribute("to").getValue();
if (lookupfield != null && lookupfield [0] != null)
{
var householdlookupvalue = lookupfield [0].id;
}
else
{
var householdlookupvalue = " ";
}
alert("I am here2");
alert(householdlookupvalue);
}
// Prepare variables for a contact to retrieve.
var authenticationHeader = Xrm.Page.context.getAuthenticationHeader();
// Prepare the SOAP message.
var xml = ""+
""+
authenticationHeader+
""+
""+
"contact"+
""+lookupfield [0].id+""+
""+
""+
"parentcustomerid"+
""+
""+
""+
""+
"";
alert(xml );
// Prepare the xmlHttpObject and send the request.
var xHReq = new ActiveXObject("Msxml2.XMLHTTP");
xHReq.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xHReq.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
xHReq.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xHReq.setRequestHeader("Content-Length", xml.length);
xHReq.send(xml);
// Capture the result.
var resultXml = xHReq.responseXML;
alert("at results");
var errorCount = resultXml.selectNodes('//error').length;
alert("errorCount " + errorCount); ////////////////////////////////////returns 0; it shouldn't
alert("After the result XML "+resultXml .toString() + " ::::");
// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0)
{
}
// Display the retrieved value.
else
{
//Create an array to set as the DataValue for the lookup control.
var lookupData = new Array();
//Create an Object add to the array.
var lookupItem= new Object();
//Set the id, typename, and name properties to the object.
lookupItem.id = resultXml.selectSingleNode("//q1:parentcustomerid").nodeTypedValue;
lookupItem.entityType = 'account';
lookupItem.name = resultXml.selectSingleNode("//q1:parentcustomerid").getAttribute("name");
// Add the object to the array.
lookupData[0] = lookupItem;
alert(lookupitem.name)
// Set the value of the lookup field to the value of the array.
Xrm.Page.getAttribute("str_companyid").setValue(lookupData);
}
var contact = new Array();
contact = Xrm.Page.getAttribute("to").getValue();
alert("I am here");
alert(contact);
if (contact == null || contact[0].entityType != "contact" || contact.length > 1) {
return;
}
alert("inside if")
var serverUrl = Xrm.Page.context.getClientUrl();
var oDataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc/ContactSet?$select=ParentCustomerId&$filter=ContactId eq guid'" + contact[0].id + "'";
var retrieveReq = new XMLHttpRequest();
retrieveReq.open("GET", oDataSelect, false);
retrieveReq.setRequestHeader("Accept", "application/json");
retrieveReq.setRequestHeader("Content-Type", "application/json;charset=utf-8");
retrieveReq.onreadystatechange = function () {
GetContactData(this);
};
retrieveReq.send();
}
I replied in the other forum but I post here as reference and with more technical details.
The to attribute of phonecall entity is a partylist type, this means that it can handle several records from different entities. In your case you want to get the Parent Account (field parentcustomerid) if a contact is inside the to field.
Your first code contains same typo and use the msdn Retrieve example, the second code uses CRM 4.0 endpoints, they are still supported inside CRM 2011, but it's better to avoid them so you can use the REST endpoint instead of the SOAP one.
a working code in your case can be:
function setToParentAccount() {
// set only if to Field (Recipient) has 1 record and is a contact
if (Xrm.Page.getAttribute("to").getValue() != null) {
var recipient = Xrm.Page.getAttribute("to").getValue();
if (recipient.length == 1 && recipient[0].entityType == "contact") {
var contactId = recipient[0].id;
var serverUrl;
if (Xrm.Page.context.getClientUrl !== undefined) {
serverUrl = Xrm.Page.context.getClientUrl();
} else {
serverUrl = Xrm.Page.context.getServerUrl();
}
var ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";
var contactRequest = new XMLHttpRequest();
contactRequest.open("GET", ODataPath + "/ContactSet(guid'" + contactId + "')", false);
contactRequest.setRequestHeader("Accept", "application/json");
contactRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8");
contactRequest.send();
if (contactRequest.status === 200) {
var retrievedContact = JSON.parse(contactRequest.responseText).d;
var parentAccount = retrievedContact.ParentCustomerId;
if (parentAccount.Id != null && parentAccount.LogicalName == "account") {
var newParentAccount = new Array();
newParentAccount[0] = new Object();
newParentAccount[0].id = parentAccount.Id;
newParentAccount[0].name = parentAccount.Name;
newParentAccount[0].entityType = parentAccount.LogicalName;
Xrm.Page.getAttribute("str_companyid").setValue(newParentAccount);
} else {
Xrm.Page.getAttribute("str_companyid").setValue(null);
}
} else {
alert("error");
}
} else {
Xrm.Page.getAttribute("str_companyid").setValue(null);
}
}
}
to be called inside OnLoad event and OnChange event of the to field.
Being very new to SharePoint coding I have been assigned the task to create a prototype code to upload a file and setting the field values for that file that will show up when opening the sharepoint page with the file.
This has to be done from a remote machine and not the Sharepoint server itself so using the .Net objects for Sharepoint is out the question.
I quickly found out how to upload a file through the Sharepoint Web Service Copy.asmx:
void UploadTestFile() {
var file = #"C:\Temp\TestFile.doc";
string destinationUrl = "http://mysharepointserver/Documents/"
+ Path.GetFileName(file);
string[] destinationUrls = { destinationUrl };
var CopyWS = new Copy.Copy();
CopyWS.UseDefaultCredentials = true;
CopyWS.Url = "http://mysharepointserver/_vti_bin/copy.asmx";
CopyResult[] result;
byte[] data = File.ReadAllBytes(file);
FieldInformation mf1 = new FieldInformation {
DisplayName = "title",
InternalName = "title",
Type = FieldType.Text,
Value = "Dummy text"
};
FieldInformation mf2 = new FieldInformation {
DisplayName = "MyTermSet",
InternalName = "MyTermSet",
Type = FieldType.Note,
Value = "Test; Unit;"
};
CopyWS.CopyIntoItems(
"+",
destinationUrls,
new FieldInformation[] { mf1, mf2 },
data,
out result);
}
This code easily uploads any file to the target site but only fills the "title" field with info. The field MyTermSet in which I have added 3 terms allready - Test, Unit and Page - will not update with the values "Test;" and "Unit;".
Being very new to Sharepoint and me not grasping all the basics googling has told me that updating "File", "Computed" or "Lookup" fields does not work with the CopyIntoItems method, and MyTermSet being a Taxonomy field is - if I am correct - a Lookup field.
So how do I get MyTermSet updated with the values "Test;" and "Unit;" ?
I would really prefer If someone has a sample code on this. I have followed several hint-links but I am none the wiser. I have found no sample-code on this at all.
Have anyone made one single method that wraps it all? Or another method that takes in the destinationUrl from the file upload and updates the Term Set/Taxonomy field.
Puzzling together what I have found so far, I am now able to do as I wanted. But I would really like to be able to get the Taxonomy field GUIDs dynamically and NOT having to explicitly set them myself:
void UploadTestFile(string FileName, string DocLib, Dictionary<string, string> Fields = null) {
//Upload the file to the target Sharepoint doc lib
string destinationUrl = DocLib + Path.GetFileName(FileName);
string[] destinationUrls = { destinationUrl };
var CopyWS = new Copy.Copy();
CopyWS.UseDefaultCredentials = true;
CopyWS.Url = new Uri(new Uri(DocLib), "/_vti_bin/copy.asmx").ToString();
CopyResult[] result;
var data = File.ReadAllBytes(FileName);
CopyWS.CopyIntoItems(
"+",
destinationUrls,
new FieldInformation[0],
data,
out result);
if (Fields == null) return; //Done uploading
//Get the ID and metadata information of the fields
var list = new ListsWS.Lists();
list.UseDefaultCredentials = true;
var localpath = new Uri(DocLib).LocalPath.TrimEnd('/');
var site = localpath.Substring(0, localpath.LastIndexOf("/")); //Get the site of the URL
list.Url = new Uri(new Uri(DocLib), site + "/_vti_bin/lists.asmx").ToString(); //Lists on the right site
FieldInformation[] fiOut;
byte[] filedata;
var get = CopyWS.GetItem(destinationUrl, out fiOut, out filedata);
if (data.Length != filedata.Length) throw new Exception("Failed on uploading the document.");
//Dictionary on name and display name
var fieldInfos = fiOut.ToDictionary(x => x.InternalName, x => x);
var fieldInfosByName = new Dictionary<string, FieldInformation>();
foreach (var item in fiOut) {
if (!fieldInfosByName.ContainsKey(item.DisplayName)) {
fieldInfosByName.Add(item.DisplayName, item);
}
}
//Update the document with fielddata - this one can be extended for more than Text and Note fields.
if (!fieldInfos.ContainsKey("ID")) throw new Exception("Could not get the ID of the upload.");
var ID = fieldInfos["ID"].Value; //The ID of the document we just uploaded
XDocument doc = new XDocument(); //Creating XML with updates we need
doc.Add(XElement.Parse("<Batch OnError='Continue' ListVersion='1' ViewName=''/>"));
doc.Element("Batch").Add(XElement.Parse("<Method ID='1' Cmd='Update'/>"));
var methNode = doc.Element("Batch").Element("Method");
//Add ID
var fNode = new XElement("Field");
fNode.SetAttributeValue("Name", "ID");
fNode.Value = ID;
methNode.Add(fNode);
//Loop each field and add each Field
foreach (var field in Fields) {
//Get the field object from name or display name
FieldInformation fi = null;
if (fieldInfos.ContainsKey(field.Key)) {
fi = fieldInfos[field.Key];
}
else if (fieldInfosByName.ContainsKey(field.Key)) {
fi = fieldInfosByName[field.Key];
}
if (fi != null) {
//Fix for taxonomy fields - find the correct field to update
if (fi.Type == FieldType.Invalid && fieldInfos.ContainsKey(field.Key + "TaxHTField0")) {
fi = fieldInfos[field.Key + "TaxHTField0"];
}
else if (fi.Type == FieldType.Invalid && fieldInfosByName.ContainsKey(field.Key + "_0")) {
fi = fieldInfosByName[field.Key + "_0"];
}
fNode = new XElement("Field");
fNode.SetAttributeValue("Name", fi.InternalName);
switch (fi.Type) {
case FieldType.Lookup:
fNode.Value = "-1;#" + field.Value;
break;
case FieldType.Choice:
case FieldType.Text:
fNode.Value = field.Value;
break;
case FieldType.Note: //TermSet's
var termsetval = "";
var terms = field.Value.Split(';');
foreach (var term in terms) {
termsetval += "-1;#" + term + ";";
}
fNode.Value = termsetval.TrimEnd(';');
break;
default:
//..Unhandled type. Implement if needed.
break;
}
methNode.Add(fNode); //Adds the field to the XML
}
else {
//Field does not exist. No use in uploading.
}
}
//Gets the listname (not sure if it is the full path or just the folder name)
var listname = new Uri(DocLib).LocalPath;
var listcol = list.GetListCollection(); //Get the lists of the site
listname = (from XmlNode x
in listcol.ChildNodes
where x.Attributes["DefaultViewUrl"].InnerText.StartsWith(listname, StringComparison.InvariantCultureIgnoreCase)
select x.Attributes["ID"].InnerText).DefaultIfEmpty(listname).First();
//Convert the XML to XmlNode and upload the data
var xmldoc = new XmlDocument();
xmldoc.LoadXml(doc.ToString());
list.UpdateListItems(listname, xmldoc.DocumentElement);
}
Then I call it like this:
var fields = new Dictionary<string, string>();
fields.Add("Test", "Dummy Text");
fields.Add("MrTermSet", "Page|a4ba29c1-3ed5-47e9-b43f-36bc59c0ea5c;Unit|4237dfbe-22a2-4d90-bd08-09f4a8dd0ada");
UploadTestFile(#"C:\Temp\TestFile2.doc", #"http://mysharepointserver/Documents/", fields);
I would however prefer to call it like this:
var fields = new Dictionary<string, string>();
fields.Add("Test", "Dummy Text");
fields.Add("MrTermSet", "Page;Unit");
UploadTestFile(#"C:\Temp\TestFile2.doc", #"http://mysharepointserver/Documents/", fields);