The code below, is an attempt to get (download) files from a sharepoint.
If I try this on my local version, it works like a charm. I can select all items in the document library.
There are several methods I've tried, and I could post some of them here if you like. I can download corrupt files, but even when the link is wrong.
If I try this on the TeamSite in Office 365, I get an exception that my link is wrong. But I'm referring to the same site (instead of localhost/dev/ im referring to http://mysite.com/TeamSite/dev/). Any idea what the difference can be? Does Microsoft block something so external connections aren't allowed?
private void btnDownload_Click(object sender, EventArgs e)
{
if (comboBox1.Items.Count > 0 && comboBox1.SelectedIndex != -1)
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.ShowDialog();
using (SPSite site = new SPSite("http://localhost/dev/"))
{
using (SPWeb web = site.OpenWeb())
{
SPFolder myLibrary = web.Folders["Management"];
foreach (SPFile file in myLibrary.Files)
{
if (file.Name == comboBox1.SelectedItem.ToString())
{
byte[] bytes = file.OpenBinary();
try
{
FileStream fs = new FileStream(dialog.FileName, FileMode.Create, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bytes);
bw.Close();
MessageBox.Show("File downloaded to: " + dialog.FileName);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
}
}
else
{
MessageBox.Show("Select file to download");
}
}
This is the Exception message:
The Web application at http://www.gtest.nl/TeamSite/ could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application.
You can not connect to sharepoint site, deployed on another computer like this.
You should use Client Context
for example:
string siteUrl = "http://MyServer/sites/MySiteCollection";
ClientContext clientContext = new ClientContext(siteUrl);
Web oWebsite = clientContext.Web;
ListCollection collList = oWebsite.Lists;
clientContext.Load(collList);
clientContext.ExecuteQuery();
foreach (SP.List oList in collList)
{
Console.WriteLine("Title: {0} Created: {1}", oList.Title, oList.Created.ToString());
}
you could find more examples on Client Context here
There is allready an example of file download from sharepoint through clientContext.
Related
Through C#, I'm trying to download a file from SharePoint (SharePoint 2016). Below is the code I'm using:
site = new ClientContext(url);
//credential setting has no issues. So I am skipping it. I am using NetworkCredentials
site.Load(web);
site.ExecuteQuery();
List list = web.Lists.GetByTitle("Documents");
site.Load(list);
site.ExecuteQuery();
site.Load(list.RootFolder);
site.ExecuteQuery();
site.Load(list.RootFolder.Folders);
site.ExecuteQuery();
Folder folder = web.GetFolderByServerRelativeUrl(sharePointPath);
site.Load(folder);
site.ExecuteQuery();
site.Load(folder.Files);
site.ExecuteQuery();
While the last "site.ExecuteQuery()" is being executed, an exception is thrown:
ExceptionMessage: File not found
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream
But, there are files in that path and manually we are able to upload and download with the same credentials. URLs, Paths, etc have been double-checked and no issues with that.
When I print "folder.ItemCount", it is printing the correct no. of files in the folder. Only in ExecuteQuery for loading files, it is throwing exception.
Build settings: .NET framework 4.5 and x64
In other posts, people advised to change to .NET 3.5 but it was for SharePoint 2010. Further, changing it to 3.5 ends up in lot of build errors for me.
Please help in fixing this.
Here is the code snippet to download a file from SharePoint default Document library and save into a local folder:
static void Main(string[] args)
{
string siteUrl = "http://sp2016/sites/dev";
ClientContext clientContext = new ClientContext(siteUrl);
var list = clientContext.Web.Lists.GetByTitle("Documents");
var listItem = list.GetItemById(5);
clientContext.Load(list);
clientContext.Load(listItem, i => i.File);
clientContext.ExecuteQuery();
var fileRef = listItem.File.ServerRelativeUrl;
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, fileRef);
var fileName = Path.Combine(#"C:\Test", (string)listItem.File.Name);
using (var fileStream = System.IO.File.Create(fileName))
{
fileInfo.Stream.CopyTo(fileStream);
}
}
I was working with collection and above solution did not work for me, here is how I did so that it can help someone.
List list = web.Lists.GetByTitle("Events");
ListItemCollection listItems = list.GetItems(cmlqry);
context.Load(listItems);
context.ExecuteQuery();
if (listItems != null)
{
foreach (var listItem in listItems)
{
Console.WriteLine("Id: {0}, Title: {1}", listItem["ID"].ToString(), listItem["Title"].ToString());
context.Load(listItem.AttachmentFiles);
context.ExecuteQuery();
foreach (var file in listItem.AttachmentFiles)
{
Console.WriteLine("File: {0}", file.FileName);
var fileRef = file.ServerRelativeUrl;
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, fileRef);
var fileName = Path.Combine(#"C:\temp\Events\", String.Format("{0}_{1}", listItem.Id, file.FileName));
using (var fileStream = System.IO.File.Create(fileName))
{
fileInfo.Stream.CopyTo(fileStream);
}
}
}
}
I am using PhoneGap to develop application for Windows, Android and iOS platform.
I have one problem and need expert assistance from you guys.
I have created one plugin for Windows Phone. Plugin is basically download images from URL and stored in isolated storage folder inside Downloads folder this is working successfully.
Now my problem is does there any way to access isolated storage files from javascript. for example i have downloaded one image and stored in isolated storage ("Download/logo.png) now i have to set this image to my html image source. e.g. <img src="ms-appdata:///local/Downloads/logo.png"/>
But couldn't get success. i have tried several way without luck.
I have using following code to save files in isolated storage.
//This code is working fine for saving image from url to isolated storage
IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication();
//Create directory if does not exists
if (ISF.DirectoryExists(IMAGE_FOLDER_PATH) == false)
{
Debug.WriteLine("Directory created");
ISF.CreateDirectory(IMAGE_FOLDER_PATH);
}
WebClient client = new WebClient();
string modeuleName = hamBurgerMenu[MODULENAME_COLUMN_INDEX];
client.OpenReadCompleted += (s, e) =>
{
if (e.Error == null)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
string fullPath = Path.Combine(IMAGE_FOLDER_PATH, modeuleName + ".png");
var bi = new BitmapImage();
bi.SetSource(e.Result);
var wb = new WriteableBitmap(bi);
using (var isoFileStream = isoStore.CreateFile(fullPath))
{
var width = wb.PixelWidth;
var height = wb.PixelHeight;
Extensions.SaveJpeg(wb, isoFileStream, width, height, 0, 100);
}
}
});
}
};
client.OpenReadAsync(new Uri(imageURL, UriKind.Absolute));
I have tried following solutions but couldn't get success at all.
<img src="file:///C:|/Data/Users/DefApps/AppData/{9DB..............0CC}/local/Downloads/logo.png"/>
<img src="ms-appdata:///local/Downloads/logo.png"/>
<img src="ms-appx:///Downloads/logo.png"/>
Your comments or suggestion would be highly appreciated!
Thanks & Regards,
Imdadhusen
I have resolved the issue using below code. The purpose of posting answer is it might help other people who are searching for the same.
Now i am saving downloaded images at app's Local Folder.
Following function will download image from live URL.
private void downloadImage(string imageURL, string[] hamBurgerMenu)
{
string ext = Path.GetExtension(imageURL.Trim());
try
{
WebClient client = new WebClient();
client.OpenReadCompleted += (s, e) =>
{
if (e.Error == null)
{
Deployment.Current.Dispatcher.BeginInvoke(async () =>
{
await saveImage(e.Result, imageURL);
});
}
else
{
//Download Image Not Found
}
};
client.OpenReadAsync(new Uri(imageURL, UriKind.Absolute));
}
catch (Exception e)
{
//Download Error
}
}
Now i am saving the downloaded image using below function
// Save a downloaded images to the app’s local folder.
public async Task saveImage(Stream photoToSave, string imageURL)
{
StorageFile photoFile = null;
try
{
string ext = Path.GetExtension(imageURL.Trim());
photoFile = await localFolder.CreateFileAsync(ext, CreationCollisionOption.ReplaceExisting);
using (var photoOutputStream = await photoFile.OpenStreamForWriteAsync())
{
await photoToSave.CopyToAsync(photoOutputStream);
}
}
catch (Exception e)
{
//Error while saving file
}
}
Now we can access the file using following path at HTML page or Client side script
Important:- <APP_ID> e.g. {8A027331-C7348-182D188-8A02473-1247801} should be replace with your Application ID. It will be 32 digit key.
<img src="C:\\Data\\Users\\DefApps\\AppData\\<APP_ID>\\local\\ Mobile.jpg" alt="Mobile.jpg" />
I'm attempting to automate a mail merge process using c#, a DataSet, and OpenXML. I have a complete working example when running locally. When publishing to our webserver however, I'm getting an Access Denied error despite even going so far as to grant Full Control everywhere.
Here is the code leading up to the error message:
try
{
var strTemplateTestFile = strMergeBuildingLocation.Replace(".docx", "_Test.docx");
// Don't continue if the template file name is not found
if (!File.Exists(strTemplateFileName))
throw new Exception("TemplateFileName (" + strTemplateFileName + ") does not exist");
foreach (var dr in dsData.Tables[0].Rows)
{
string strFileName;
if (doesDestinationExist(strMergeBuildingLocation))
{
File.Copy(strTemplateFileName, strTemplateTestFile, true);
strFileName = strTemplateTestFile;
}
else
{
File.Copy(strTemplateFileName, strMergeBuildingLocation, true);
strFileName = strMergeBuildingLocation;
}
var pkg = Package.Open(strFileName, FileMode.Open, FileAccess.ReadWrite);
using (var docGenerated = WordprocessingDocument.Open(pkg))
The problem falls within the last line upon attempting to open docGenerated.
The error message I'm receiving is:
Access to the path 'docx path' is denied.
The file copies as expected and is able to be opened and modified manually. There's nothing within the folders that would be restricting access to the file. Does anyone have any thoughts as to what the issue could be?
I think the problem is here in this line.
var pkg = Package.Open(strFileName, FileMode.Open, FileAccess.ReadWrite);
using (var docGenerated = WordprocessingDocument.Open(pkg))
Here you are trying to open the document twice.
Try this,
/* Open WordProcessing document package based on filename */
//------------------------------------------------------------------------------------------------Start
public static WordprocessingDocument OpenPackage(WordprocessingDocument package, string inputFileName, bool editable)
{
bool copied = false;
while (!copied)
{
try
{
package = WordprocessingDocument.Open(inputFileName, editable);
copied = true;
}
catch (Exception e)
{
if (e is FileFormatException)
{
package = null;
break;
}
if (e is IOException)
{
copied = false;
}
if (e is ZipException)
{
package = null;
break;
}
}
}
return package;
}
This will give you the WordprocessingDocument package if it exists and available. If file does not exists, null will be returned.If file locked, will open package when file released.
Hope this helps.! Thank you!
I have build an app with a webbrowser in it. It's working fine but when I try to navigate to an adress like bla.pdf the webbrowser shows nothing.
I solved this problem with automatically open the Internet Explorer if the adress is linking to a pdf file.
Is there a better solution? I want to open that PDF file in my own app and I dont want to open the Internet Explorer everytime. Any suggestions?
If you've got a locally downloaded PDF that is in Isolated Storage you can launch the PDF Reader application (or any other applications registered to open PDF files) using LaunchFileAsync.
private async void LaunchFileButton_Click(object sender, RoutedEventArgs rea)
{
// Access isolated storage.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Access the PDF.
StorageFile pdfFile = await local.GetFileAsync("file1.pdf");
// Launch the bug query file.
Windows.System.Launcher.LaunchFileAsync(pdfFile);
}
(adapted from MSDN, see section on "launching a file").
If it's a remote URL then you can use LaunchUriAsync (which will use IE to download the file first).
You will need to try this on a device with the PDF Reader application installed - it won't work on the Emulator.
You should read following article if you are not familiar with Async: MSDN Asynchronous Programming with Async and Await
I couldn't test my app because my WP8 Phone is currently not available and I can't install an PDF reader on the emulator.
Call following method to start the download
WebClient pdfDownloader = null;
string LastFileName = ""; //To save the filename of the last created pdf
private void StartPDFDownload(string URL)
{
pdfDownloader = new WebClient(); //prevents that the OpenReadCompleted-Event is called multiple times
pdfDownloader.OpenReadCompleted += DownloadPDF; //Create an event handler
pdfDownloader.OpenReadAsync(new Uri(URL)); //Start to read the website
}
async void DownloadPDF(object sender, OpenReadCompletedEventArgs e)
{
byte[] buffer = new byte[e.Result.Length]; //Gets the byte length of the pdf file
await e.Result.ReadAsync(buffer, 0, buffer.Length); //Waits until the rad is completed (Async doesn't block the GUI Thread)
using (IsolatedStorageFile ISFile = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
LastFileName = "tempPDF" + DateTime.Now.Ticks + ".pdf";
using (IsolatedStorageFileStream ISFileStream = ISFile.CreateFile(LastFileName))
{
await ISFileStream.WriteAsync(buffer, 0, buffer.Length);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + Environment.NewLine + ex.HResult,
ex.Source, MessageBoxButton.OK);
//Catch errors regarding the creation of file
}
}
OpenPDFFile();
}
private async void OpenPDFFile()
{
StorageFolder ISFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
try
{
IStorageFile ISFile = await ISFolder.GetFileAsync(LastFileName);
await Windows.System.Launcher.LaunchFileAsync(ISFile);
//http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj206987%28v=vs.105%29.aspx
}
catch (Exception ex)
{
//Catch unknown errors while getting the file
//or opening the app to display it
}
}
To call these methods from your WebBrowser-Control you need to catch the navigating event.
YourWebBrowserControl.Navigating += YourWebBrowserControl_Navigating;
void YourWebBrowserControl_Navigating(object sender, NavigatingEventArgs e)
{
if(e.Uri.AbsolutPath.EndsWith("pdf"))
{
StartPDFDownload(e.Uri.ToString());
}
}
Don't forget that you'll have to delete the files created someday.
Try this to open a PDF from a WebControl:
void MyWebBrowserControl_Navigating(object sender, NavigatingEventArgs e)
{
if (e.Uri.AbsolutPath.ToLower().EndsWith(".pdf"))
{
var success = Windows.System.Launcher.LaunchUriAsync(e.Uri);
}
}
I basically want to transfer a file from the client to the file storage server without actual login to the server so that the client cannot access the storage location on the server directly. I can do this only if i manually login to the storage server through windows login. I dont want to do that. This is a Web-Based Application.
Using the link below, I wrote a code for my application. I am not able to get it right though, Please refer the link and help me ot with it...
Uploading files to file server using webclient class
The following is my code:-
protected void Button1_Click(object sender, EventArgs e)
{
filePath = FileUpload1.FileName;
try
{
WebClient client = new WebClient();
NetworkCredential nc = new NetworkCredential(uName, password);
Uri addy = new Uri("\\\\192.168.1.3\\upload\\");
client.Credentials = nc;
byte[] arrReturn = client.UploadFile(addy, filePath);
Console.WriteLine(arrReturn.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
The following line doesn't execute...
byte[] arrReturn = client.UploadFile(addy, filePath);
This is the error I get:
An exception occurred during a
WebClient request
Ah, it seems (and with good reason), the FileUpload can only save files to the web server and its drives. So my first thought won't work.
But: if you have the necessary permissions, couldn't you just save the file that you get in the FileUpload to that UNC path using standard System.IO calls?? Something like :
protected void Button1_Click(object sender, EventArgs e)
{
try
{
string completeFileName =
Path.Combine(#"\\192.168.1.3\upload", FileUpload1.FileName);
BinaryReader br = new BinaryReader(FileUpload1.PostedFile.InputStream);
FileStream fstm = new FileStream(completeFileName, FileMode.Create, FileAccess.ReadWrite);
BinaryWriter bw = new BinaryWriter(fstm);
byte[] buffer = br.ReadBytes(FileUpload1.PostedFile.ContentLength);
br.Close();
bw.Write(buffer);
bw.Flush();
bw.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
If you expect very large files to be uploaded, you might want to transfer the data from the BinaryReader to the BinaryWriter in chunks - instead of allocating just a single buffer - but that's just an implementation detail, really.
I had the same issue a few days ago, I solved it by creating a user on the Web server and on the storage server with the same user name and password, I then impersonated the user in the web.config file.
NB: The user should have RW permissions in the directory where you want to store the files.