Programmatically checkout webpage sharepoint - sharepoint

Im trying to remove all content in page. but i get an exception when i trying to do this, it says that the file is not checked out and i have to do this. And when i use file.CheckOut() I see that the file is checked out to the systemAccount and i get exception:
The file is CheckedOut to another user
How to do that i can ignore the CheckOut to the current/specific user
this is what i have tried
SPSecurity.RunWithElevatedPrivileges(delegate()
{
var webMngr = web.GetLimitedWebPartManager("Sidor/default.aspx", PersonalizationScope.Shared);
List<System.Web.UI.WebControls.WebParts.WebPart> webPartList = (from System.Web.UI.WebControls.WebParts.WebPart webPart in webMngr.WebParts select webPart).ToList();
SPFile file = web.GetFile(web.Url+"Sidor/default.aspx");
web.AllowUnsafeUpdates = true;
if (file.CheckOutType == SPFile.SPCheckOutType.Online)
{
file.CheckIn("Comment");
}
file.CheckOut();
object _lock = new object();
lock (_lock)
{
for (int i = 0; i < webMngr.WebParts.Count; i++)
{
webMngr.DeleteWebPart(webPartList[i]);
}
}
web.AllowUnsafeUpdates = false;
});

file.forceCheckOut = false
here the msdn function
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.forcecheckout(v=office.15).aspx

Related

Copying existing files into a server SharePoint

I'm facing of difficulties to change a files into CSV and save it into local environment. How can I achieve this? Try to look around but seem like not what I'm looking for.
I'm running on SharePoint 2010. Before this, this code only grab data from SharePoint and turn it into xlsx and update it into our web.
private static void GenerateSPGroupUsersReport() //
{
Log("Generate Sharepoint Group Users Report");
DataSet dsSecurityReport = new DataSet();
string ConnectedWebURL = ConfigurationManager.AppSettings["SPGroupUsersWebURL"];
//string[] strURL = ConnectedWebURL.Split(';');
DataTable dTblSPGroupUser = new DataTable();
dTblSPGroupUser.Columns.Add("SiteURL", typeof(string));
dTblSPGroupUser.Columns.Add("SharepointGroup", typeof(string));
dTblSPGroupUser.Columns.Add("User", typeof(string));
// Hafees add 10/22/2019
dTblSPGroupUser.Columns.Add("UserLanID", typeof(string));
dTblSPGroupUser.Columns.Add("Email", typeof(string));
SPSite site = new SPSite(ConnectedWebURL);
SPWebApplication webApp = site.WebApplication;
foreach (SPSite s in webApp.Sites)
{
SPGroupCollection groupCol = s.RootWeb.SiteGroups;
foreach (SPGroup group in groupCol)
{
// Hafees include group.Users, user.Email
foreach (SPUser user in group.Users)
{
dTblSPGroupUser.Rows.Add(s.Url, group.Name, user.Name, user.LoginName, user.Email);
}
//bool contains = dTblSPGroupUser.AsEnumerable().Any(rowC => group.Name == rowC.Field<string>("SharepointGroup"));
//if (!contains)
//{
// foreach (SPUser user in group.Users)
// {
// dTblSPGroupUser.Rows.Add(s.Url, group.Name, user.Name);
// }
//}
}
}
DataSet dsSPGroup = new DataSet();
dsSPGroup.Tables.Add(dTblSPGroupUser);
SaveIntoSPLibrary(site, dsSPGroup, "GroupUsers_" + ConnectedWebURL.Replace("http://", "").Replace("https://", "").Replace(":", "-").Trim());
Log("Generate Sharepoint Group Users Report Complete");
}
// This is where I generate the group of user report.
private static void SaveIntoSPLibrary(SPSite site, DataSet ds, string fileName)
{
string UIResourceServerRelativeWebURL = ConfigurationManager.AppSettings["UIResourceServerRelativeWebURL"];
using (SPWeb web = site.OpenWeb(UIResourceServerRelativeWebURL))
{
byte[] byteArray = GenerateExcelFile(ds);
string CustomReportLibrary = ConfigurationManager.AppSettings["CustomReportLibrary"];
string strFileName = String.Format(fileName + ".{0}.xlsx", DateTime.Today.ToString("yyyyMMdd"));
Log("Saving into SP Library. " + CustomReportLibrary + strFileName);
web.AllowUnsafeUpdates = true;
SPFile file = web.Files.Add(CustomReportLibrary + strFileName, byteArray, true);
file.Item["Year"] = DateTime.Now.ToString("yyyy");
file.Item["Month"] = string.Format("{0}. {1}", DateTime.Now.Month, DateTime.Now.ToString("MMMM"));
file.Item.Update();
file.Update();
web.AllowUnsafeUpdates = false;
}
}
// This is where the files save into xlsx and update it into SharePoint Library.
I try to do a copy of SaveIntoLibrary with abit of modification, I change to CSV files and create a new configurationManager which it will point into my local directory. But seem I'm wrong at somewhere. The files still didn't get into my local directory. Please advice.
You should export the DataTable report data to local CSV,
Check the code in this thread, this will output the csv file so you could save to your local.
var dataTable = GetData();
StringBuilder builder = new StringBuilder();
List<string> columnNames = new List<string>();
List<string> rows = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
columnNames.Add(column.ColumnName);
}
builder.Append(string.Join(",", columnNames.ToArray())).Append("\n");
foreach (DataRow row in dataTable.Rows)
{
List<string> currentRow = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
object item = row[column];
currentRow.Add(item.ToString());
}
rows.Add(string.Join(",", currentRow.ToArray()));
}
builder.Append(string.Join("\n", rows.ToArray()));
Response.Clear();
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.csv");
Response.Write(builder.ToString());
Response.End();

Sharepoint list does not exist on the site efter but it exists in my code when debugging

I shall eventually create a sharepoint calendar. I want to create a eventslist here but I'll get this strange error here.
I create a a eventslist and then check [to see] if its already created. If it is, not I want to create it but then my testLabel says that its already exists.
When I try to delete the list, on the myButton_Click, it gives me this error:
Microsoft.SharePoint.Client.ServerException: List 'CompanyCalendar'
does not exist at site with URL 'http://server1'.
Code
using Microsoft.SharePoint.Client;
namespace CalendarWeb.Pages
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Uri hostWeb = new Uri(Request.QueryString["SPHostUrl"]);
using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity))
{
Web web = clientContext.Web;
ListCreationInformation listCreator = new ListCreationInformation();
listCreator.Title = "CompanyCalendar";
listCreator.Description = "Workcalendar";
listCreator.TemplateType = (int)ListTemplateType.Events;
var ifListExcists = web.Lists.GetByTitle(listCreator.Title);
if (ifListExcists == null)
{
web.Lists.Add(listCreator);
clientContext.ExecuteQuery();
testLabel.Text = "The " + listCreator.Title + " list was created";
}
else
{
testLabel.Text = "List already excist";
}
}
}
protected void myButton_Click(object sender, EventArgs e)
{
Uri hostWeb = new Uri(Request.QueryString["SPHostUrl"]);
using (var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity))
{
Web web = clientContext.Web;
var deleteList = web.Lists.GetByTitle("CompanyCalendar");
deleteList.DeleteObject();
clientContext.ExecuteQuery();
testLabel.Text = "list deleted";
}
}
}
}
When I look at my server1 site the list is not there but in the code it seems like its there since my variable "ifListExcists" is never null.
Your ifListExists variable would never be null because its not executed on server.
Use following method to check if list exists or not:
private bool ValdiateList(ClientContext clientContext, string listName, out List existingList)
{
Web web = clientContext.Web;
existingList =null;
ListCollection lists = web.Lists;
var existingLists
= clientContext.LoadQuery(lists.Where(list => list.Title == listName));
clientContext.ExecuteQuery();
existingList = existingLists.FirstOrDefault();
return (existingList != null);
}

Sharepoint: How to upload files with metadata including Taxonomy fields through web services

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);

Allowing UserProfileManager Permissions in SharePoint 2010

I am trying to display a list of users in a custom webpart using the UserProfileManager. For some reason, I can view the webpart and all profiles are output to the screen (maybe because I am an administrator). But when a standard user logs in, they encounter a 403 page.
I have done some reading up on this and I know its something to do with permissions. This is what I have in my code:
private DataTable GetProfiles()
{
DataTable dtUserProfile = new DataTable();
//...DataTable Columns
SPSecurity.RunWithElevatedPrivileges(delegate()
{
Guid guid = SPContext.Current.Site.ID;
using (SPSite intranet = new SPSite(guid))
{
SPUserToken userToken = intranet.Owner.UserToken;
//Get current intranet context.
SPServiceContext sContext = SPServiceContext.GetContext(intranet);
UserProfileManager profileManager = new UserProfileManager(sContext);
int totalUsers = int.Parse(profileManager.Count.ToString());
Random random = new Random();
for (int i = 0; i < NumberOfUsersToRetrieve(NoOfProfiles, totalUsers); i++)
{
int randNumber = random.Next(1, totalUsers);
DataRow drUserProfile;
UserProfile up = profileManager.GetUserProfile(randNumber);
drUserProfile = dtUserProfile.NewRow();
drUserProfile["DisplayName"] = up.DisplayName;
drUserProfile["FirstName"] = up["FirstName"].Value;
drUserProfile["LastName"] = up["LastName"].Value;
drUserProfile["Department"] = up["Department"].Value;
drUserProfile["ContactNumber"] = up["Office"].Value;
drUserProfile["MySiteUrl"] = up.PublicUrl;
dtUserProfile.Rows.Add(drUserProfile);
}
}
});
return dtUserProfile;
}
My code basically gets a random collection of users depending on the number of users I want to return.
Is it possible to create a SPUserToken for a user that all permissions needed to retrieve the user profiles?
Thanks!
I appreciate this question is old, but I had the exact same problem. To help the original poster and other users, I have altered the code from the original post to the following:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
SPSite sc = new SPSite(SPContext.Current.Site.ID);
SPServiceContext context = SPServiceContext.GetContext(sc);
HttpContext currentContext = HttpContext.Current;
HttpContext.Current = null;
UserProfileManager profileManager = new UserProfileManager(context);
IEnumerator profileEnum = profileManager.GetEnumerator();
while (profileEnum.MoveNext())
{
UserProfile up = (UserProfile)profileEnum.Current;
if ((up["FirstName"] != null && up["FirstName"].Value != null && !String.IsNullOrEmpty(up["FirstName"].Value.ToString()))
&& (up.PublicUrl != null && !String.IsNullOrEmpty(up.PublicUrl.ToString())))
{
DataRow drUserProfile;
drUserProfile = dtUserProfile.NewRow();
drUserProfile["DisplayName"] = up.DisplayName;
drUserProfile["FirstName"] = up["FirstName"].Value;
drUserProfile["LastName"] = up["LastName"].Value;
drUserProfile["Department"] = up["Department"].Value;
drUserProfile["Location"] = up["SPS-Location"].Value;
drUserProfile["MySiteUrl"] = up.PublicUrl.ToString().Replace(#"\", #"\");
dtUserProfile.Rows.Add(drUserProfile);
}
}
}
HttpContext.Current = currentContext;
Hopefully this code should resolve the error.
Instead of getting the UserToken of SPSite.Owner, have you tried SPSite.SystemAccount.UserToken, or SPWeb.AllUsers["user"].UserToken;
I'd do the latter if possible, rule of least privileges etc.

Adding description to WebPartPage when creating the page

I am following this (http://msdn.microsoft.com/en-us/library/ms450826.aspx) method to add a webpartpage (samplewpp.aspx) and it works. However, I need to add one line description as well. How?
You need to add a Content Editor Web Part (CEWP) to the page and then add your description to this. The CEWP allows you to put text/html onto a page.
To do this programatically then follow something like this code by Razi bin Rais :-
AddAndFillCEWP("http://server","/" ,"/Pages/blank.aspx","this text is adding via code","Header","CEWP WebPart");
private void AddAndFillCEWP(string siteUrl, string webName, string pageUrl, string textCEWP, string zoneId, string title)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite spSiteTest = new SPSite(siteUrl))
{
using (SPWeb web = spSiteTest.OpenWeb(webName))
{
try
{
web.AllowUnsafeUpdates = true;
SPFile file = web.GetFile(pageUrl);
if (null != file)
{
using (SPLimitedWebPartManager mgr = file.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
if (null != mgr)
{
//create new webpart object
ContentEditorWebPart contentEditor = new ContentEditorWebPart();
//set properties of new webpart object
contentEditor.ZoneID = zoneId;
contentEditor.Title = title;
contentEditor.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal;
contentEditor.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.TitleAndBorder;
//Add content to CEWP
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("Root");
xmlElement.InnerText = textCEWP;
contentEditor.Content = xmlElement;
contentEditor.Content.InnerText = xmlElement.InnerText;
//Add it to the zone
mgr.AddWebPart(contentEditor, contentEditor.ZoneID, 0);
web.Update();
}
}
}
}
finally
{
web.AllowUnsafeUpdates = false;
}
}
}
});
}

Resources