Delete an item on a Sharepoint List (C#) - c#

I want to read an Item from a Document Library and then Delete it. The problem I get a Security Exception: "The security validation for this page is invalid"
What am I doing wrong? I'm executing the commands with Elevated Privilages!
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite oSiteCollection = new SPSite(SharePointInfo.SubSiteUrl))
{
using (SPWeb oWebsite = oSiteCollection.OpenWeb())
{
SPList uploadFilesLibrary = oWebsite.Lists[SharePointInfo.UploadFilesLibraryName];
if (files.Count > 0)
{
foreach (var fileToSend in files)
{
try{
/*SPFile file = uploadFilesLibrary.Items.Cast<SPListItem>()
.Where(x => x.Name.Equals(fileToSend))
.Select(x => x.File).First();*/
SPListItem p = uploadFilesLibrary.Items.Cast<SPListItem>()
.Where(x => x.Name.Equals(fileToSend)).First();
byte[] binaryFile = p.File.OpenBinary();
p.Delete();
aux = new FileAttachesForm(fileToSend, System.Convert.ToBase64String(binaryFile));
rtn.Add(aux);
}catch (Exception ex){
string errMessage = string.Format("Error al descargar el fichero desde SP: {0} - Pila: {1}", ex.Message, ex.StackTrace);
Logger.LogError(errMessage, ex);
throw ex;
}
}
}
}
}
});
return rtn;
}

Try adding this inside of your if:
oSiteCollection.AllowUnsafeUpdates = true;
And take a look at this related question:
SharePoint Security Validation Issue while updating metadata (The security validation for this page is invalid)

Related

Session.SaveChanges() does not work on latest page

Have a quote application, which we fill the data and send from source system to receiver system. That receiver system will be sending status of that quote(Success/Failed) as Acknowledgement to source system. We have an option to revise the same quote. whenever we revise the quote, the Status is inherited from previous quote. we need to clear the latest revision's status. which is not happening. but it clears previous revision's status. Could anyone help me.
if (plm == "PLM")
{
if (id.Revision != 0)
{
var javascriptSerializer = new JavaScriptSerializer();
var urn = line.CustomProperties?.FirstOrDefault(k => k.Key.ToLower() == "urn")?.Value;
oRecordLog.WriteToLogFile("Updating DBValue");
//initilizing document store object to query the documents from database.
IDocumentStore ravenDB = new DocumentStore { Url = "http://localhost:8072", DefaultDatabase = "Configit.Quote" }.Initialize();
try
{
List<Document> docs;
using (var session = ravenDB.OpenSession())
{
oRecordLog.WriteToLogFile("Opened RavenDB session");
//getting the URN value.
var javaScriptSerializer = new JavaScriptSerializer();
string urnString = urn;
ModelKeyValuePair urnKeyValue = new ModelKeyValuePair();
urnKeyValue.Key = "URN";
urnKeyValue.Value = javaScriptSerializer.Serialize(urnString);
//wait for 5 seconds before the next query
docs = session.Query<Document>().Customize(x => x.WaitForNonStaleResults(TimeSpan.FromSeconds(5))).Where(x => x.Lines.Any(l => l.Properties.Any(ID => ID == urnKeyValue))).ToList();
try
{
oRecordLog.WriteToLogFile("docs " + docs.Count);
//processing one by one document from RavenDB.
foreach (var doc in docs)
{
string quoteGuid = null;
if (doc.LinesCount > 0)
{
int lineCnt = doc.LinesCount;
// processing each line in the docuement getting the quoteID
foreach (var quoteline in doc.Lines)
{
if ((quoteline.Properties.ContainsKey("Urn")) || (quoteline.Properties.ContainsKey("URN")) || (quoteline.Properties.ContainsKey("urn")))
{
Guid lGuid = quoteline.LineId;
var quote_ForID = _quoteStorage.GetQuote(new QuoteRevisionId(id.QuoteId, id.Revision));
var urn_ForQuoteId = quoteline.Properties?.FirstOrDefault(k => k.Key == "URN")?.Value;
if (GetUniqueRefnum(quote_ForID, quoteline) == urn_ForQuoteId)
{
quoteGuid = doc.DocumentId.ToString();
oRecordLog.WriteToLogFile("quoteGuid " + quoteGuid);
var TransferStatus = quoteline.Properties?.FirstOrDefault(p => p.Key == "TransferStatus");
var PLMDetailedStatus = quoteline.Properties?.FirstOrDefault(p => p.Key == "PLMDetailedStatus");
TransferStatus.Value = "";
PLMDetailedStatus.Value = "";
}
}
}
}
else
{
oRecordLog.WriteToLogFile("Quote ID not found");
}
}
session.SaveChanges();
}
catch (Exception e)
{
//printing error logs in Acknowledgement.txt.
oRecordLog.WriteToLogFile(" exception caught main Stacktrace-----" + e.StackTrace);
oRecordLog.WriteToLogFile(" exception caught main Message-----" + e.Message);
oRecordLog.WriteToLogFile(" exception caught main Inner Exception-----" + e.InnerException);
return null;
}
}
}
catch (Exception e)
{
//printing error logs in Acknowledgement.txt.
oRecordLog.WriteToLogFile(" exception caught main Stacktrace-----" + e.StackTrace);
oRecordLog.WriteToLogFile(" exception caught main Message-----" + e.Message);
oRecordLog.WriteToLogFile(" exception caught main Inner Exception-----" + e.InnerException);
return null;
}
orderupdateservice.BeginUpload(lineCount, linid, TargetSystem.Plm);
}
else
{
oRecordLog.WriteToLogFile("This is new quote");
orderupdateservice.BeginUpload(lineCount, linid, TargetSystem.Plm);
}
}

How to check Sharepoint connectivity before ClientContext.ExecuteQuery

I am very new to sharepoint. What is the fastest and most efficient way to check Sharepoint site connectivity before ClientContext.ExecuteQuery.
ClientContext ctx = new ClientContext(ConfigurationManager.AppSettings["sharepoint siteUrl"]);
float pageLoadTime = getPageLoadTime(ctx);
if(pageLoadTime > 0.5)
{
MessageBox.Show("Sharepoint site is not available!");
return;
}
//do very heavy query
....
ctx.ExecuteQuery();
There is no such standard method to do that. But you can achieve this like following code
using (ClientContext sourceContext = new ClientContext("Sharepoint Url"))
{
try
{
sourceContext.ExecuteQuery();
List list = sourceContext.Web.Lists.GetByTitle("Test");
ListItemCollection itemColl = list.GetItems(CamlQuery.CreateAllItemsQuery());
sourceContext.Load(itemColl);
sourceContext.ExecuteQuery();
}
catch (System.Net.WebException ex)
{
if (ex.Message == "The remote server returned an error: (404) Not Found.")
{
Console.WriteLine("SharePoint not available");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
because "ExecuteQuery" is the method which connect to SharePoint through Client.svc wcf service.
Hope this helps...

Traverse files in sftp and store to azure blob

Basically i creating a azure webjob which will loop through record from a sql table which has got sftp location detail. for each sftp location, connect using sftpclient and read all files in a folder.
for each files, i connect to azure and store it in the blob.
I have done the above in single file. But wish to do in a proper object oriented way. Not sure what is the right approach. i am not very much experience in design pattern but would love if someone can recomment a right approach.
Appreciate if someone can help me to achieve this in a proper object oriented way.
Thanks
var azureBlob = AzureBlobStorage.Instance(StorageConnectionString, Containername);
List<SftpLocationData> sftps = null;
try
{
sftps = SftpLocationClient.GetSftpLocationDetails().ToList();
if (sftps == null || !sftps.Any()) return;
}
catch (Exception ex)
{
LogMessage(string.Format("Error getting sftp details : {0}", ex.Message), log);
}
foreach (var fileClient in sftps.Select(sftp => new FileTransferClient(sftp)))
{
using (var sftpClient = fileClient.CreateClient())
{
sftpClient.Connect();
var files = sftpClient.ListDirectory(path: fileClient.Data.Directory ?? ".").ToList();
if (files.Any())
{
var validFiles = files.Where(f => ext.Any(e => e == Path.GetExtension(f.Name))).ToList();
foreach (var file in validFiles)
{
var fileExists = azureBlob.FileExists(file.Name);
var blobUri = string.Empty;
var blobName = file.Name;
var fileImport = PopulateFileImportData(file);
if (fileExists)
{
int count = azureBlob.ListFiles(blobName);
blobName = (count == 0) ? blobName : String.Format("{0}_v{1}", blobName, count);
fileImport.Error = true;
fileImport.ErrorMsg = "Duplicate File";
}
fileImport.FileName = blobName;
try
{
var fileSaved = RbsClient.SaveFileImport(fileImport);
blobUri = azureBlob.UploadFile(fileSaved.FileName, sftpClient.OpenRead(file.FullName));
fileSaved.Archived = DateTime.Now;
RRClient.UpdateFile(fileSaved);
}
catch (Exception ex)
{
LogMessage(string.Format("Error saving fileimport detail : {0}", ex.Message), log);
}
if (fileImport.Error) continue;
IQueueGenerator queueGenerator = new QueueGenerator();
var queueName = queueGenerator.GetQueueName(
blobName,
fileClient.Data,
blobUri);
if (string.IsNullOrEmpty(queueName)) continue;
}
}
sftpClient.Disconnect();
}
}
}
catch (Exception ex)
{
LogMessage(string.Format("Error occurred in processing pending altapay requests. Error : {0}", ex.Message), log);
}
Hi as of my understanding you need to copy the files/folders from FTP to azure blob storage.
Step 1. Get list of SFTP locations
Step 2. Init Azure Blob Storage Connection
Step 3. Init SFTP
Step 4. Iterate Files in SFTP
Step 5. Store the file into Blob Storage
Step 6. Close SFTP connection
Step 7. Close Azure Blob Storage

Sharepoint 2013 Server Object Model. Copy permissions from one site to another during site creation

I want to copy the permissions from Site Collection A to a Site I am creating in Site Collection B in the same Web App. This is happening in a List Item Event Receiver on ItemAdded.
Here is what I have so far...
static void SetupNewSubSite(int currentYear, SPItemEventProperties properties, int siteIndexId)
{
//set properties to create my new web
string description = properties.AfterProperties["Project_x0020_Description"].ToString();
SPListItem CurrentItem = properties.ListItem;
String subSiteUrl = Convert.ToString(siteIndexId);
SPSite projectSiteCollection = new SPSite(properties.Web.Site.Url + "/" + currentYear);
SPWeb sWeb = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl);
SPWeb oWeb = projectSiteCollection.RootWeb;
SPWebCollection cWebs = oWeb.Webs;
//create the new web
SPWeb xWeb = cWebs.Add(subSiteUrl, properties.AfterProperties["Title"].ToString(),
properties.AfterProperties["Project_x0020_Description"].ToString(), 1033, "{B5B6BDD1-485A-44BC-B093-F1048271C49D}", false, false);
UpdateItemProjectUrl(CurrentItem, properties.Web.Site.Url + "/" + currentYear + "/" + subSiteUrl, currentYear);
//break inheritance and remove permissions from the new site
xWeb.BreakRoleInheritance(false);
LogMessage("Role Count: " + xWeb.RoleAssignments.Count.ToString());
while (xWeb.RoleAssignments.Count > 0)
{
xWeb.RoleAssignments.Remove(0);
}
//Get the roleassignments from the source site
SPRoleAssignmentCollection sRoleAssignments = sWeb.RoleAssignments;
LogMessage("role assignment count from source web: "+ sRoleAssignments.Count.ToString());
foreach (SPRoleAssignment sRoleAssignment in sRoleAssignments)
{
SPPrincipal sPrincipal = sRoleAssignment.Member;
LogMessage("Principal Name: " + sPrincipal.Name.ToString());
try
{
//add roleassignment to newly created web
xWeb.RoleAssignments.Add(sPrincipal);
}
catch (Exception ex)
{
LogMessage(ex.ToString());
}
}
xWeb.Update();
LogMessage("After Permissions Change");
xWeb.Dispose();
projectSiteCollection.Dispose();
oWeb.Dispose();
LogMessage("after dispose");
}
This code successfully:
1. creates a new site in the other site collection.
2. breaks inheritance on the newly created site.
3. remove the original permissions from the newly created site.
This code does not successfully:
copy over groups from the other site collection to the new site.
Found a method someone created...
http://rajeshagadi.blogspot.com/2011/04/how-to-programmatically-copy-web-level.html
public static void CopyWebRoleAssignments(SPWeb sourceWeb, SPWeb destinationWeb)
{
//Copy Role Assignments from source to destination web.
foreach (SPRoleAssignment sourceRoleAsg in sourceWeb.RoleAssignments)
{
SPRoleAssignment destinationRoleAsg = null;
//Get the source member object
SPPrincipal member = sourceRoleAsg.Member;
//Check if the member is a user
try
{
SPUser sourceUser = (SPUser)member;
destinationWeb.EnsureUser(sourceUser.LoginName);//EDITED
SPUser destinationUser = destinationWeb.AllUsers[sourceUser.LoginName];
if (destinationUser != null)
{
destinationRoleAsg = new SPRoleAssignment(destinationUser);
}
}
catch
{ }
if (destinationRoleAsg == null)
{
//Check if the member is a group
try
{
SPGroup sourceGroup = (SPGroup)member;
SPGroup destinationGroup = destinationWeb.SiteGroups[sourceGroup.Name];
destinationRoleAsg = new SPRoleAssignment(destinationGroup);
}
catch
{ }
}
//At this state we should have the role assignment established either by user or group
if (destinationRoleAsg != null)
{
foreach (SPRoleDefinition sourceRoleDefinition in sourceRoleAsg.RoleDefinitionBindings)
{
try { destinationRoleAsg.RoleDefinitionBindings.Add(destinationWeb.RoleDefinitions[sourceRoleDefinition.Name]); }
catch { }
}
if (destinationRoleAsg.RoleDefinitionBindings.Count > 0)
{
//handle additon of an existing permission assignment error
try { destinationWeb.RoleAssignments.Add(destinationRoleAsg); }
catch (ArgumentException) { }
}
}
}
//Finally update the destination web
destinationWeb.Update();
}
Remade the functionality as an Extension method without the try-catch handling of workflow:
public static void CopyWebRoleAssignmentsFrom(this SPWeb web, SPWeb fromWeb)
{
web.BreakRoleInheritance(false);
foreach (SPRoleAssignment sourceRoleAsg in fromWeb.RoleAssignments)
{
SPRoleAssignment destinationRoleAsg = null;
SPPrincipal member = sourceRoleAsg.Member;
if (member is SPUser)
{
SPUser sourceUser = member as SPUser;
SPUser user = web.SiteUsers[sourceUser.LoginName];
destinationRoleAsg = new SPRoleAssignment(user);
}
else if (member is SPGroup)
{
SPGroup sourceGroup = (SPGroup)member;
SPGroup group = web.SiteGroups[sourceGroup.Name];
destinationRoleAsg = new SPRoleAssignment(group);
}
foreach (SPRoleDefinition sourceRoleDefinition in sourceRoleAsg.RoleDefinitionBindings)
{
destinationRoleAsg.RoleDefinitionBindings.Add(web.RoleDefinitions[sourceRoleDefinition.Name]);
}
if (destinationRoleAsg.RoleDefinitionBindings.Count > 0)
{
web.RoleAssignments.Add(destinationRoleAsg);
}
}
web.Update();
}

Windows 8/RT delete from sqlite using linq

I have SQLite database in isolated storage in Windows Store App.
I use SQLite for Windows Runtime
When i want to delete all table entry I use follow method:
public static async void DeleteAllProjects()
{
var storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("myDb.sqlite");
using (var db = new SQLiteConnection(storageFile.Path))
{
try
{
db.DeleteAll<Projects>();
}
catch
(Exception ex)
{
Debug.WriteLine("Delete error " + ex.Message);
}
}
}
All work like a charm.
But when i need to delete part of entries:
public static async void Delete(List<Projects> projects)
{
var storageFile = await ApplicationData.Current.LocalFolder.GetFileAsync("myDb.sqlite");
using (var db = new SQLiteConnection(storageFile.Path))
{
try
{
foreach (var project in projects)
{
var existingProject = (db.Table<Projects>().Where(
p => p.id == project.Id)).FirstOrDefault();
if (existingProject != null)
{
db.Delete<Projects>(existingProject);
}
}
}
catch
(Exception ex)
{
Debug.WriteLine("Delete error " + ex.Message);
}
}
}
I handled exeption with
ex.Message = "Cannot delete Projects: it has no PK" string
Can somebody help me?

Categories

Resources