Web.GetFileByServerRelativeUrl throws "Value does not fall within expected range" - c#

I have a SP Online site where I store Documents, I have no issues adding/retrieving documents but in the delete flow I get an error during retrieval of a File object.
public static void DeleteDocument()
{
using (ClientContext ctx = ClientContextFactory.Create("https://my-sponline-site.sharepoint.com/sites/documentsite"))
{
Web web = ctx.Web;
ctx.Load(web);
ctx.ExecuteQuery();
string relativeUrl = "/Documents/images.jpg";
File file = web.GetFileByServerRelativeUrl(relativeUrl);
ctx.Load(file);
file.DeleteObject();
ctx.ExecuteQuery();
}
}
Full Url of the file is "https://my-sponline-site.sharepoint.com/sites/documentsite/Documents/images.jpg" (No more accessible 2016-12-07)
When I execute this, I get a ServerException :
Value does not fall within the expected range.
The Context is working fine as I'm able to add/retrieve items from the library and the context user is administrator.
I tried adding the web url to the relativeUrl so it would be "/documentsite/Documents/images.jpg" but I get the same error.
I can't seem to figure this out, any suggestions?
Thanks

string relativeUrl = "/sites/documentsite/Documents/images.jpg";

Related

Google DriveService Files.List() not returning results

Edit:
I've tried granting the SA access to my personal drive (within the organization Workspace) to do some troubleshooting. After granting rights to the SA to a particular folder and rewriting the code to examine that folder, it successfully returned information about files within the test folder. The conclusion is the SA has been set-up correctly by our IT department and does have adequate scope and rights to read files in our organizations Workspace. So, the questions remain: why can't it return information about files in a Shared Drive? What other parameters need to be set in order to get it to return those files? Are there entirely other functions that need to be used? I did notice the deprecated TeamDrives.List() function, but the guidance when trying to use it was to use Files.List() as I had written originally.
--- end edit ---
We have a Google Workspace environment. I've been granted a Service Account (SA) by our IT department and am trying to use it to help maintain access rights. The SA has been granted Content Manager rights to a shared drive instance.
I've tried following along this YouTube tutorial. In stepping through the code execution, it appears to log in correctly, but it is not returning any files. I've tried substituting the full URL for the file ID of the root folder I'd like to examine, but then it returns a 404 error, so I think it is finding the correct folder.
If the file ID is used the code runs without errors, it simply returns no files (and there are hundreds of folders and files within the root).
Any suggestions?
namespace DriveQuickstart
{
class Program
{
static string[] Scopes = { DriveService.Scope.DriveReadonly };
private const string PathToServiceAccountKeyFile = #"<path to jason Service Account file>";
private const string ServiceAccountEmail = #"<Service Account "email">";
static void Main(string[] args)
{
MainAsync().Wait();
}
static async Task MainAsync()
{
var credential = GoogleCredential.FromFile(PathToServiceAccountKeyFile)
.CreateScoped(new[] { DriveService.ScopeConstants.Drive });
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential
});
var request = service.Files.List();
request.IncludeItemsFromAllDrives = true;
request.SupportsAllDrives = true;
request.Q = "parents in '<id of "root" folder in shared drive>'";
FileList results = await request.ExecuteAsync();
foreach (var driveFile in results.Files)
{
Console.WriteLine($"{driveFile.Name} {driveFile.MimeType} {driveFile.Id}");
}
}
}
}
OK, it appears the #DAIMTO example is specific to personal drives. The Q() parameter syntax is incorrect for Team drives in the example. To make it work in Team environment:
IncludeItemsFromAllDrives parameter must be set to true
SupportsAllDrives parameter must be set to true
the Q search parameter syntax for finding specific directories is:
Q = "'folder_ID' in parents and mimeType = 'application/vnd.google-apps.folder'"; -- or mimeType of your choice
(note: this is reversed from the youtube example of "parents in 'folder_ID'")

How to add value to a custom column while uploading document into a SharePoint document library as an item using C#?

I have a console application which tries to upload a document into a share point document library list.
I am successfully able to do it and also I am able to fill one of the custom Column(Column name is : "Category") value while uploading the file using C#.
I have tried to fill another custom column(Column name is : "Related Assets") value using the same procedure but i get the error stating the provided column name does not exist but when i see in actual share point portal it does exist.
So not able to solve this issue. Even i tried couple of methods as given below and i get same error message in terms of the column does not exist or it has been deleted or not able to recognize it.
Please find the screenshot of SharePoint showing the list of columns:
Please find the code i have till now which upload the document into SharePoint portal.
public static async Task<string> UploadReleaseNoteDocumentintoSpPortal(string releasenotefilepath, string releasenotefilename, string clientid, string clientsecret)
{
string status = string.Empty;
try
{
Console.WriteLine("Trying to Upload Release note file into Share Point Portal...");
string siteUrl = "<<Sp site URL>>";
Console.WriteLine("Connecting to Share Point Portal...");
var ClientContext = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, clientid, clientsecret);
ClientContext.Load(ClientContext.Web, p => p.Title);
await ClientContext.ExecuteQueryAsync();
Console.WriteLine(ClientContext.Web.Title);
var web = ClientContext.Web;
Console.WriteLine("Connected successfully to Share Point Portal...");
List DocumentsList = web.Lists.GetByTitle("Accelerators Documents");
ClientContext.Load(DocumentsList.RootFolder);
await ClientContext.ExecuteQueryAsync();
Console.WriteLine("Reading and loading the list named : Accelerators Documents from SP");
Console.WriteLine("Converting the release note document into byte array");
byte[] bytes = System.IO.File.ReadAllBytes(releasenotefilepath);
MemoryStream stream = new MemoryStream(bytes);
Console.WriteLine("Storing the release note Data into File Create information object of SharePoint");
FileCreationInformation FileCreateInfo = new FileCreationInformation();
FileCreateInfo.Content = bytes;
FileCreateInfo.ContentStream = stream;
FileCreateInfo.Overwrite = true;
FileCreateInfo.Url = DocumentsList.RootFolder.ServerRelativeUrl + #"\" + releasenotefilename;
Console.WriteLine("Adding file to SharePoint");
var ReleaseNoteFiledata = DocumentsList.RootFolder.Files.Add(FileCreateInfo);
ReleaseNoteFiledata.Update();
ReleaseNoteFiledata.ListItemAllFields["Category"] = "Release Notes";
//ReleaseNoteFiledata.ListItemAllFields["Related Assets"] = "<<Desired Value>>";
//IN Above commented line i get the error stating Microsoft.SharePoint.Client.ServerException:
//'Column 'Related Assets' does not exist. It may have been deleted by another user.
//But in actual site if we see it exists as you can see in above screenshot
ReleaseNoteFiledata.ListItemAllFields.Update();
ClientContext.Load(ReleaseNoteFiledata);
await ClientContext.ExecuteQueryAsync();
Console.WriteLine("Adding file to SharePoint Completed Successfully...");
return status = "Successful";
}
catch (Exception ex)
{
Console.WriteLine("Exception occured while trying to upload Release note file into CoP Portal :" + ex.Message);
return status = "Error/Exception";
}
}
Please find the error message i get while trying to add value to another custom column present in SharePoint:
Microsoft.SharePoint.Client.ServerException: 'Column 'Related Assets' does not exist. It may have been deleted by another user.
Even if i use the ReleaseNoteFiledata.SetFileProperties() and pass the values as a dictionary key value pair containing the column name and its value then also i get the same error for the second custom column. If i keep only the category custom column then it works perfectly without any issue as you can see in the screenshot above.
If i select the record and see the details or properties in the SharePoint the Related assets column symbol is some like in below screenshot:
Please let me know if the supporting documents are fine or still if my issue is not understandable so that i can re frame it or provide more screenshots.
Please help me in solving the above issue or how to make this column recognizable or readable or identifiable in the code.
Thanks in Advance
Regards
ChaitanyaNG
You need to use the internal name of the column 'Related Assets' in your code. It should be Related_x0020_Assets.
You could check the internal name of the column by go to list settings-> click the column, you would see the internal name in the url.

MOSS 2007, programmatically downloading document folder; Can't connect to Document folder

I'm attempting to programmatically download all files from a document folder on a Sharepoint 2007 site. So far, I'm able to connect to the site, but am having issues connecting to the folders and download them.
try{
using(SPSite site = new SPSite("http://mysharepointserver/sites/subsite")){
using(SPWeb web = site.OpenWeb()){
Console.Write("Connected to site");
SPFolder testFolder = web.Folder["testFolder"];
//example method downloading folder
downloadFolder(testFolder);
}
}
}
catch(Exception e){
Log(e.ToString());
}
My console write works,so I know I am connecting to the site correctly.
My log file outputs:
System.ArgumentException: Value does not fall within the expected range.
at Microsoft.SharePoint.SPListCollection.GetListByName(String strListName, Boolean bThrowException)
at Microsoft.SharePoint.SPListCollection.get_Item(String strListName)
I also attempted to print out the following:
using(SPWeb web = site.OpenWeb()){
Console.Write("Connected to site");
Console.Write(web.lists);
SPFolder testFolder = web.Folder["testFolder"];
//example method downloading folder
downloadFolder(testFolder);
}
Which outputs the following to console:
Connected to site
Microsoft.SharePoint.SPListCollection
But I'm not certain how to navigate through SPListCollection to retrieve my folder "testFolder"
Any help would be appreciated. Thanks!
When you connect to share point site, there are different types of libraries. Library that contains documents and folders is DocumentLibrary and not ListLibrary. Once you have the item / library by ID, cast it to correct SPDocumentLibrary to retrieve items you want.
Use https://learn.microsoft.com/en-us/dotnet/api/microsoft.sharepoint.spdocumentlibrary?view=sharepoint-server to get different methods and properties of DocumentLibrary to retrieve the testFolder.
Example of accessing document library item from :https://social.msdn.microsoft.com/Forums/en-US/5ee7fb55-5d90-4d28-8990-bf00479f891f/how-to-get-spdocumentlibrary?forum=sharepointdevelopmentprevious
SPSite siteCollection = this.Site;
SPWeb site = this.Web;
// obtain query string values
string ListId = Request.QueryString["ListId"];
string ItemId = Request.QueryString["ItemId"];
// create list object and list item object
SPList list = site.Lists[new Guid(ListId)];
SPListItem item = list.Items.GetItemById(Convert.ToInt32(ItemId));
// query for information about list and list item
string ListTitle = list.Title;
string ItemTitle = item.Title;
if (list is SPDocumentLibrary) {
SPDocumentLibrary documentLibrary = (SPDocumentLibrary)list;
string DocumentTemplateUrl = documentLibrary.DocumentTemplateUrl;
SPFile file = item.File;
string FileAuthor = file.Author.Name;
string FileSize = file.TotalLength.ToString("0,###") + " bits";
}

Why I can't insert a file into a SharePoint list via code? It goes into exception, seems that the access is denied

I am very new in SharePoint (I am using SharePoint 2013) and I am experiencing a strange problem. This is very strange because in another section of my application it works fine (in another subsite).
So basically into SharePoint I have a SharePoint list named Protocollo.
My code contains the following lines that add a document (a file) into a subfolder of the previous SharePoint List:
internal static int InsertItem(Dictionary<string, object> prot, Documento doc, bool assignVisibility, bool newItem)
{
int state = 0;
SPListItem item = null;
UOR currUOR = null;
List<UOR> path = new List<UOR>();
SPWeb web = SPContext.Current.Web;
string siglaAOO = web.Properties["sigla_aoo"];
DBConnection dbConfig = ArxeiaProtocollo.Util.ProtUtils.InitializeDBConnection();
dbConfig.Database = siglaAOO;
string username = web.CurrentUser.LoginName;
try
{
SPList list = web.Lists["Protocollo"];
web.AllowUnsafeUpdates = true;
SPFolderCollection folders = list.RootFolder.SubFolders;
SPFolder annoFolder;
DateTime dateProt = Convert.ToDateTime(prot["Data protocollo"]);
try
{
annoFolder = folders[dateProt.Year.ToString()];
}
catch
{
annoFolder = folders.Add(dateProt.Year.ToString());
}
SPFolder meseFolder;
try
{
meseFolder = annoFolder.SubFolders[dateProt.Month.ToString("D2")];
}
catch
{
meseFolder = annoFolder.SubFolders.Add(dateProt.Month.ToString("D2"));
}
SPFolder dayFolder;
try
{
dayFolder = meseFolder.SubFolders[dateProt.Day.ToString("D2")];
}
catch
{
dayFolder = meseFolder.SubFolders.Add(dateProt.Day.ToString("D2"));
}
SPFile spFile = dayFolder.Files.Add(doc.Nome, doc.File, true);
............................................................
............................................................
............................................................
}
As you can see the previous code retrievce the Protocollo list from the current website allowing updates on it by:
SPList list = web.Lists["Protocollo"];
web.AllowUnsafeUpdates = true;
Then into this list it creates (it doesn't exist) a gerarcic folders structure for year (annoFolder), month (meseFolder) and day (dayFolder).
It works fine, I tried to delete these folder structure from my SharePoint site and performing this method it is created again, infact this is what I obtained:
As you can see it correctly creates this folder structure into my SharePoint list (named Protocollo) into the current website.
Ok finnally my code try to insert a document into the last subfolder (the dayfolder) by:
SPFile spFile = dayFolder.Files.Add(doc.Nome, doc.File, true);
I am passing to the Add() method: the name of the file, the byte array representing the file and the true boolean value.
The problem is that performing this line I obtain the following exception that is not providing information:
{Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
Then in my front end it appears a "denied access" popup window.
The strange thing is that another sites in my SharePoint that uses the same code have no problem. Another strange thing is that manually uploading the file into this location of the list it works fine so I think that it should not be a user permission problem.
Some idea? What can I try to do to solve this strange problem?
SharePoint codes run using the Application Pool user in IIS not the user that you have logged in to SharePoint, so it is common to get an access denied error even when you have access. So I would suggest you check the permission for the AppPool account on the Protocollo library. Or you can use SPSecurity.RunWithElevatedPrivileges if you have trust in the user that will run the code.
Beware of the pitfalls though.
Here is a sample usage:
Guid siteId = SPContext.Current.Site.ID;
Guid webId = SPContext.Current.Web.ID;
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(siteId))
{
using (SPWeb web = site.OpenWeb(webId))
{
// Your code here
}
}
});

When renaming a file in SharePoint via client object model, the filename gets trimmed if there's a dot in between

I wrote a small application using the SharePoint client object model, which renames all files inside a SharePoint 2010 document library.
Everything works well, except if the filename should contain a dot somewhere in between, it get's trimmed, starting with the dot.
For example, when the new filename should be "my fi.le name" it ends up with "my fi" in SharePoint. The extension of the file (.pdf in my case) stays correct by the way.
Here's what I'm doing (in general):
ClientContext clientContext = new ClientContext("http://sp.example.com/thesite);
List list = clientContext.Web.Lists.GetByTitle("mydoclibrary");
ListItemCollection col = list.GetItems(CamlQuery.CreateAllItemsQuery());
clientContext.Load(col);
clientContext.ExecuteQuery();
foreach (var doc in col)
{
if (doc.FileSystemObjectType == FileSystemObjectType.File)
{
doc["FileLeafRef"] = "my fi.le name";
doc.Update();
clientContext.ExecuteQuery();
}
}
When I'm renamig the file in SharePoint manually via browser (edit properties), everything works as it should: The dot stays and the filename won't be trimmed at all.
Is "FileLeafRef" the wrong property? Any ideas what's the cause here?
Using FileLeafRef property it is possible to update file name but without extension.
How to rename file using SharePoint CSOM
Use File.MoveTo method to rename a file:
public static void RenameFile(ClientContext ctx,string fileUrl,string newName)
{
var file = ctx.Web.GetFileByServerRelativeUrl(fileUrl);
ctx.Load(file.ListItemAllFields);
ctx.ExecuteQuery();
file.MoveTo(file.ListItemAllFields["FileDirRef"] + "/" + newName, MoveOperations.Overwrite);
ctx.ExecuteQuery();
}
Usage
using (var ctx = new ClientContext(webUrl))
{
RenameFile(ctx, "/Shared Documents/User Guide.docx", "User Guide 2013.docx");
}

Categories

Resources