How to upload a file to a document library in sharepoint? - c#

I have a byte[] data and I want to upload it to sharepoint site using c#. I also want to pass credentials for it. Can anyone please guide me.
The code I tried is:
Uri destUri = new Uri("http://test.net/excel/docs/Forms/AllItems.aspx/");
WebRequest req = WebRequest.Create(destUri);
req.Method = "PUT";
req.Credentials = CredentialCache.DefaultCredentials;
using (req.GetRequestStream())
{
string destFilename = #"\\test.net\excel\docs\501.xls";
byte[] data = new byte[10];
System.IO.File.WriteAllBytes(destFilename, data);
}
ERROR:
Access Denied

Current user should have add permissions on this library
public void UploadFileToDocmentLibrary(Byte[] contentArray)
{
using (SPSite sharePointtopLevelSite = new SPSite("http://localhost"))
{
SPWeb websiteCollection = sharePointtopLevelSite.AllWebs["webName"];
websiteCollection.AllowUnsafeUpdates = true;
websiteCollection.Lists.IncludeRootFolder = true;
SPList docLibrary = websiteCollection.Lists["listName"];
SPFile file = websiteCollection.Files.Add(websiteCollection.Url.ToString() + "/" + docLibrary.Title.ToString() + "/" + "fileName.ext", contentArray);
file.Update();
}
}
If user without permissions should do it, use RunWithElevatedPrivileges statement

If I understood your requirements properly, you need to upload file into SharePoint On-Premise, right? There are several options on how to accomplish it.
Send file via HTTP POST using .NET
At least the following components could be utilized for that purpose:
HttpWebRequest
WebClient
HttpClient
Example
The example demonstrates how to upload file using WebClient.UploadFile Method:
public static void UploadFile(Uri targeUri, ICredentials credentials, string fileName)
{
using (var client = new WebClient())
{
client.Credentials = credentials;
//client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
var targetFileUri = targeUri + "/" + Path.GetFileName(fileName);
client.UploadFile(targetFileUri, "PUT", fileName);
}
}
Usage
var filePath = #"C:\Documents\SharePoint User Guide.docx";
var credentials = new NetworkCredential(userName, password, domain);
UploadFile(new Uri("https://contoso.sharepoint.com/documents"),credentials, filePath);
Using Microsoft SharePoint Server Object Model
using (var site = new SPSite(url))
{
using (var web = site.OpenWeb())
{
var list = web.Lists.TryGetList(listTitle);
var targetFolder = list.RootFolder;
var fileContent = System.IO.File.ReadAllBytes(fileName);
var fileUrl = Path.GetFileName(fileName);
targetFolder.Files.Add(fileUrl, fileContent);
}
}
Using Microsoft SharePoint Client Object Model
SharePoint 2010 Client Components SDK
SharePoint 2013 Client Components SDK
How to upload a file to a SharePoint site using File.SaveBinaryDirect Method
using (var ctx = new ClientContext(url))
{
ctx.Credentials = new NetworkCredential(userName, password, domain);
using (var fs = new FileStream(fileName, FileMode.Open))
{
var fi = new FileInfo(fileName);
var list = ctx.Web.Lists.GetByTitle(listTitle);
ctx.Load(list.RootFolder);
ctx.ExecuteQuery();
var fileUrl = String.Format("{0}/{1}", list.RootFolder.ServerRelativeUrl, fi.Name);
Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, fileUrl, fs, true);
}
}
Using SharePoint Web Services
How to upload file using Copy Web Service:
var webUri = new Uri("http://contoso.sharepoint.com");
string sourceUrl = #"C:\Documents\SharePoint User Guide.docx";
string destinationUrl = webUri + "/documents/SharePoint User Guide 2013.docx";
var fieldInfo = new FieldInformation();
FieldInformation[] fieldInfos = { fieldInfo };
CopyResult[] result;
using (var proxyCopy = new Copy())
{
proxyCopy.Url = webUri + "/_vti_bin/Copy.asmx";
proxyCopy.Credentials= new NetworkCredential(userName, password, domain);
var fileContent = System.IO.File.ReadAllBytes(sourceUrl);
proxyCopy.CopyIntoItems(sourceUrl, new[] { destinationUrl }, fieldInfos, fileContent, out result);
}

Related

C# Application to upload file to SharePoint with MFA

I am creating a Windows Form Application to insert data into MSSQL but also upload a file of user's choosing to SharePoint.
I tried to use the below code, however I have some serious problem due to Multi-Factor Authentication (MFA) not being lifted for my service account. IT is very firm on this matter.
string SiteUrl = "https://company.sharepoint.com/sites/mySite";
string DocumentLibrary = "Documents";
string FileName = #chkAttach1.Text.ToString();
string CustomerFolder = "Application Test";
string Username = "testuser";
string Password = "123";
foreach (char c in Password)
{ securePassword.AppendChar(c); }
var olCred = new SharePointOnlineCredentials(UserName, securePassword);
using (ClientContext cContext = new ClientContext(SiteUrl))
{
cContext.Credentials = olCred;
Web web = cContext.Web;
FileCreationInformation newFile = new FileCreationInformation();
byte[] FileContent = System.IO.File.ReadAllBytes(FileName);
newFile.ContentStream = new System.IO.MemoryStream(FileContent);
newFile.Url = System.IO.Path.GetFileName(FileName);
Microsoft.SharePoint.Client.List docLib = web.Lists.GetByTitle(DocumentLibrary);
Microsoft.SharePoint.Client.Folder uplFold = docLib.RootFolder.Folders.Add(CustomerFolder);
uplFold.Update();
Microsoft.SharePoint.Client.File uplFile = uplFold.Files.Add(newFile);
cContext.Load(docLib);
cContext.Load(uplFile);
cContext.ExecuteQuery();
}
So obviously the above is not working.
Speaking to a fellow from IT, he advised me to use API, but I have difficulties in finding a sample code online to upload a file to SharePoint using the user's current credentials.
Any advice?

Accessing Sharepoint online with MFA through C#

I'd like to download a file from Sharepoint online using a non-interactive C# program.
Recently MFA was enabled, and since then I'm unable to get the files with any user through my code, though I can still access it through the portal web access.
At first I have tried using the following, getting an The sign-in name or password does not match one in the Microsoft account system. when executing the query (using either username#mydomain.com or username#mydomain.onmicrosoft.com)
var ctx = new ClientContext(Properties.Settings.Default.SharepointBaseUrl)
{
Credentials = credentials,
};
var web = ctx.Web;
ctx.Load(web);
try
{
ctx.ExecuteQuery();
}
catch (Exception ex)
{
return string.Empty;
}
var fileUrl = $"{web.ServerRelativeUrl}/{file.Location}";
var fi = Microsoft.SharePoint.Client.File.OpenBinaryDirect(ctx, fileUrl);
Then I generated an AppId and AppSecret, and used the following code:
var authenticationManager = new OfficeDevPnP.Core.AuthenticationManager();
var ctx = authenticationManager.GetAppOnlyAuthenticatedContext(
"https://mydomain.sharepoint.com/sites/defaultcollection/MyDir",
appId,
appSecret);
But got a 401 unauthorized when trying to access the file with SharePoint.Client.File.OpenBinaryDirect(ctx, fileUrl);
Use File.OpenBinaryStream() instead like this:
using Microsoft.SharePoint.Client;
using OfficeDevPnP.Core;
using System.IO;
string siteUrl = "https://tenant.sharepoint.com/";
using (var ctx = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, "yourappid", "yourappsecret"))
{
ctx.Load(ctx.Web, p => p.Title);
ctx.ExecuteQuery();
Console.WriteLine(ctx.Web.Title);
Microsoft.SharePoint.Client.File file = ctx.Web.GetFileByUrl("https://tenant.sharepoint.com/Shared%20Documents/test.txt");
ctx.Load(file);
ctx.ExecuteQuery();
string filepath = #"C:\temp\" + file.Name;
Microsoft.SharePoint.Client.ClientResult<Stream> mstream = file.OpenBinaryStream();
ctx.ExecuteQuery();
using (var fileStream = new System.IO.FileStream(filepath, System.IO.FileMode.Create))
{
mstream.Value.CopyTo(fileStream);
}
};

Download Objects from S3 Bucket using c#

Im trying to download object from S3 bucket facing below issue
The Security token included in the request is Invalid .
Please check and correct where is the mistake.
Below is my code
1. Get Temporary credentails:
main()
{
string path = "http://XXX.XXX.XXX./latest/meta-data/iam/security-credentials/EC2_WLMA_Permissions";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(path);
request.Method = "GET";
request.ContentType = "application/json";
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
dynamic metaData = JsonConvert.DeserializeObject(result);
_awsAccessKeyId = metaData.AccessKeyId;
_awsSecretAccessKey = metaData.SecretAccessKey;
}
}
Create SessionAWSCredentials instance:
SessionAWSCredentials tempCredentials =
GetTemporaryCredentials(_awsAccessKeyId, _awsSecretAccessKey);
//GetTemporaryCredentials method:
private static SessionAWSCredentials GetTemporaryCredentials(
string accessKeyId, string secretAccessKeyId)
{
AmazonSecurityTokenServiceClient stsClient =
new AmazonSecurityTokenServiceClient(accessKeyId,
secretAccessKeyId);
Console.WriteLine(stsClient.ToString());
GetSessionTokenRequest getSessionTokenRequest =
new GetSessionTokenRequest();
getSessionTokenRequest.DurationSeconds = 7200; // seconds
GetSessionTokenResponse sessionTokenResponse =
stsClient.GetSessionToken(getSessionTokenRequest);
Console.WriteLine(sessionTokenResponse.ToString());
Credentials credentials = sessionTokenResponse.Credentials;
Console.WriteLine(credentials.ToString());
SessionAWSCredentials sessionCredentials =
new SessionAWSCredentials(credentials.AccessKeyId,
credentials.SecretAccessKey,
credentials.SessionToken);
return sessionCredentials;
}
Get files from S3 using AmazonS3Client:
using (IAmazonS3 client = new AmazonS3Client(tempCredentials,RegionEndpoint.USEast1))
{
GetObjectRequest request = new GetObjectRequest();
request.BucketName = "bucketName" + #"/" + "foldername";
request.Key = "Terms.docx";
GetObjectResponse response = client.GetObject(request);
response.WriteResponseStreamToFile("C:\\MyFile.docx");
}
We do something a little simpler for interfacing with S3 (downloads and uploads)
It looks like you went the more complex approach. You should try just using the TransferUtility instead:
TransferUtility fileTransferUtility =
new TransferUtility(
new AmazonS3Client("ACCESS-KEY-ID", "SECRET-ACCESS-KEY", Amazon.RegionEndpoint.CACentral1));
// Note the 'fileName' is the 'key' of the object in S3 (which is usually just the file name)
fileTransferUtility.Download(filePath, "my-bucket-name", fileName);
NOTE: TransferUtility.Download() returns void because it downloads the file to the path specified in the filePath argument. This may be a little different than what you were expecting but you can still open a FileStream to that path afterwards and manipulate the file all you want. For example:
using (FileStream fileDownloaded = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
// Do stuff with our newly downloaded file
}
Bucketname, Accesskey and secretkey, I took from web config. You could type manually.
public void DownloadObject(string imagename)
{
RegionEndpoint bucketRegion = RegionEndpoint.USEast1;
IAmazonS3 client = new AmazonS3Client(bucketRegion);
string accessKey = System.Configuration.ConfigurationManager.AppSettings["AWSAccessKey"];
string secretKey = System.Configuration.ConfigurationManager.AppSettings["AWSSecretKey"];
AmazonS3Client s3Client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey), Amazon.RegionEndpoint.USEast1);
string objectKey = "EMR" + "/" + imagename;
//EMR is folder name of the image inside the bucket
GetObjectRequest request = new GetObjectRequest();
request.BucketName = System.Configuration.ConfigurationManager.AppSettings["bucketname"];
request.Key = objectKey;
GetObjectResponse response = s3Client.GetObject(request);
response.WriteResponseStreamToFile("D:\\Test\\"+ imagename);
}
//> D:\Test\ is local file path.
Following is how I download it. I need to download only .zip files in this case. Restricting to only required file types (.zip in my case), helped me to avoid errors related to (416) Requested Range Not Satisfiable
public static class MyAWS_S3_Helper
{
static string _S3Key = System.Configuration.ConfigurationManager.ConnectionStrings["S3BucketKey"].ConnectionString;
static string _S3SecretKey = System.Configuration.ConfigurationManager.ConnectionStrings["S3BucketSecretKey"].ConnectionString;
public static void S3Download(string bucketName, string _ObjectKey, string downloadPath)
{
IAmazonS3 _client = new AmazonS3Client(_S3Key, _S3SecretKey, Amazon.RegionEndpoint.USEast1);
TransferUtility fileTransferUtility = new TransferUtility(_client);
fileTransferUtility.Download(downloadPath + "\\" + _ObjectKey, bucketName, _ObjectKey);
_client.Dispose();
}
public static async Task AsyncDownload(string bucketName, string downloadPath, string requiredSunFolder)
{
var bucketRegion = RegionEndpoint.USEast1; //Change it
var credentials = new BasicAWSCredentials(_S3Key, _S3SecretKey);
var client = new AmazonS3Client(credentials, bucketRegion);
var request = new ListObjectsV2Request
{
BucketName = bucketName,
MaxKeys = 1000
};
var response = await client.ListObjectsV2Async(request);
var utility = new TransferUtility(client);
foreach (var obj in response.S3Objects)
{
string currentKey = obj.Key;
double sizeCheck = Convert.ToDouble(obj.Size);
int fileNameLength = currentKey.Length;
Console.WriteLine(currentKey + "---" + fileNameLength.ToString());
if (currentKey.Contains(requiredSunFolder))
{
if (currentKey.Contains(".zip")) //This helps to avoid errors related to (416) Requested Range Not Satisfiable
{
try
{
S3Download(bucketName, currentKey, downloadPath);
}
catch (Exception exTest)
{
string messageTest = currentKey + "-" + exTest;
}
}
}
}
}
}
Here is how it is called
static void Main(string[] args)
{
string downloadPath = #"C:\SourceFiles\TestDownload";
Task awsTask = MyAWS_S3_Helper.AsyncDownload("my-files", downloadPath, "mysubfolder");
awsTask.Wait();
}
Here is what I have done to download the files from S3 bucket,
var AwsImportFilePathParcel = "TEST/TEMP"
IAmazonS3 client = new AmazonS3Client(AwsAccessKey,AwsSecretKey);
S3DirectoryInfo info = new S3DirectoryInfo(client, S3BucketName, AwsImportFilePathParcel);
S3FileInfo[] s3Files = info.GetFiles(pattenForParcel);
now in s3Files, you have all the files which are on provided location, using for each you can save all files in to your system
foreach (var fileInfo in s3Files)
{
var localPath = Path.Combine("C:\TEST\", fileInfo.Name);
var file = fileInfo.CopyToLocal(localPath);
}

Access to sharepoint 2013 site from web api

I'm working on a communication between a MVC web app developed in c# and typescript and a remote sharepoint site. I want to execute crud operations for an excel file.
I'm able to read site properties in this way:
public async Task<string> getWebTitle(string webUrl, string usr, string psw)
{
//Creating Password
const string PWD = psw;
const string USER = usr;
const string RESTURL = "{0}/_api/web?$select=Title";
//Creating Credentials
var passWord = new SecureString();
foreach (var c in PWD) passWord.AppendChar(c);
var credential = new SharePointOnlineCredentials(USER, passWord);
//Creating Handler to allows the client to use credentials and cookie
using (var handler = new HttpClientHandler() { Credentials = credential })
{
//Getting authentication cookies
Uri uri = new Uri(webUrl);
handler.CookieContainer.SetCookies(uri, credential.GetAuthenticationCookie(uri));
//Invoking REST API
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(string.Format(RESTURL, webUrl)).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
string jsonData = await response.Content.ReadAsStringAsync();
return jsonData;
}
}
}
jsonData object returns site properties.
How I can do to read a file, for example test.txt, saved in Documents folder in "mysite"?
Do you mean that you want to get the content of file in SharePoint?
We can use CSOM to achieve it.
Here is a sample for your reference:
public static void getContentOfFileInDocLib(string siteUrl, string host, string sourceListName, string fileName)
{
siteUrl = siteUrl.EndsWith("/") ? siteUrl.Substring(0, siteUrl.Length - 1) : siteUrl;
ClientContext context = new ClientContext(siteUrl);
Web web = context.Site.RootWeb;
List source = web.Lists.GetByTitle(sourceListName);
context.Load(source);
context.Load(web);
context.ExecuteQuery();
FileCollection files = source.RootFolder.Files;
Microsoft.SharePoint.Client.File file = files.GetByUrl(siteUrl + "/" + sourceListName + "/" + fileName);
context.Load(file);
context.ExecuteQuery();
FileInformation fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, file.ServerRelativeUrl);
string filePath = host + file.ServerRelativeUrl;
System.IO.Stream fileStream = fileInfo.Stream;
FileCreationInformation createFile = new FileCreationInformation();
byte[] bufferByte = new byte[1024 * 100];
System.IO.MemoryStream memory = new System.IO.MemoryStream();
int len = 0;
while ((len = fileStream.Read(bufferByte, 0, bufferByte.Length)) > 0)
{
memory.Write(bufferByte, 0, len);
}
//we get the content of file here
byte[] bytes = memory.GetBuffer();
//do something you want
//.......
}
Upload file to SharePoint Document Library.
public static void uploadFile(string siteUrl, string filePath, string fileName, string docLibName)
{
siteUrl = siteUrl.EndsWith("/") ? siteUrl.Substring(0, siteUrl.Length - 1) : siteUrl;
ClientContext context = new ClientContext(siteUrl);
List docLib = context.Web.Lists.GetByTitle(docLibName);
context.Load(docLib);
context.ExecuteQuery();
Byte[] bytes = System.IO.File.ReadAllBytes(filePath + fileName);
FileCreationInformation createFile = new FileCreationInformation();
createFile.Content = bytes;
createFile.Url = siteUrl + "/" + docLibName + "/" + fileName;
createFile.Overwrite = true;
Microsoft.SharePoint.Client.File newFile = docLib.RootFolder.Files.Add(createFile);
newFile.ListItemAllFields.Update();
context.ExecuteQuery();
}

Download a file from sharepoint

I am trying to download a file from sharepoint, I have this code and throw error code 500.
static void DownloadFile(){
string serverFilePath = "Here goes my URL, that open the file from any tab";
var password = new SecureString();
foreach (char c in Configuration.password) {
password.AppendChar(c);
}
// theese are the credentials and work fine because I tested in another method
var o365credentials = new SharePointOnlineCredentials(Configuration.userName, password);
var url = string.Format("{0}/{1}", Configuration.siteUrl, serverFilePath);
// My destination folder
string destPath = #"C:\publisher";
var request = System.Net.HttpWebRequest.Create(url);
request.Credentials = o365credentials;
using (var sReader = new StreamReader(request.GetResponse().GetResponseStream())) {
using (var sWriter = new StreamWriter(destPath)) {
sWriter.Write(sReader.ReadToEnd());
}
}
}
you can achieve this task using WebRequest in order to download files from sharepoint site:
public void DownloadFile(string serverFilePath, string destPath)
{
var url = string.Format("{0}/{1}", ServerURL, serverFilePath);
Directory.CreateDirectory(Path.GetDirectoryName(destPath)); // this method creates your directory
var request = System.Net.HttpWebRequest.Create(url);
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
using (var sReader = new StreamReader(request.GetResponse().GetResponseStream()))
{
using (var sWriter = new StreamWriter(destPath))
{
sWriter.Write(sReader.ReadToEnd());
}
}
}
if you wish to use the Client-object-model you read that:
How to get a file using SharePoint Client Object Model with only an absolute url at hand?
Edit: fixed the spelling of CreateDirectory call

Categories