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
Related
I have an API using POST Method.From this API I can download the file via Postmen tool.But I would like to know how to download file from C# Code.I have tried below code but POST Method is not allowed to download the file.
Code:-
using (var client = new WebClient())
{
client.Headers.Add("X-Cleartax-Auth-Token", ConfigurationManager.AppSettings["auth-token"]);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
string url = ConfigurationManager.AppSettings["host"] + ConfigurationManager.AppSettings["taxable_entities"] + "/ewaybill/download?print_type=detailed";
TransId Id = new TransId()
{
id = TblHeader.Rows[0]["id"].ToString()
};
List<string> ids = new List<string>();
ids.Add(TblHeader.Rows[0]["id"].ToString());
string DATA = JsonConvert.SerializeObject(ids, Newtonsoft.Json.Formatting.Indented);
string res = client.UploadString(url, "POST",DATA);
client.DownloadFile(url, ConfigurationManager.AppSettings["InvoicePath"].ToString() + CboGatePassNo.EditValue.ToString().Replace("/", "-") + ".pdf");
}
Postmen Tool:-
URL : https://ewbbackend-preprodpub-http.internal.cleartax.co/gst/v0.1/taxable_entities/1c74ddd2-6383-4f4b-a7a5-007ddd08f9ea/ewaybill/download?print_type=detailed
Header :-
Content-Type : application/json
X-Cleartax-Auth-Token :b1f57327-96db-4829-97cf-2f3a59a3a548
Body :-
[
"GLD24449"
]
using (WebClient client = new WebClient())
{
client.Headers.Add("X-Cleartax-Auth-Token", ConfigurationManager.AppSettings["auth-token"]);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
string url = ConfigurationManager.AppSettings["host"] + ConfigurationManager.AppSettings["taxable_entities"] + "/ewaybill/download?print_type=detailed";
client.Encoding = Encoding.UTF8;
//var data = "[\"GLD24449\"]";
var data = UTF8Encoding.UTF8.GetBytes(TblHeader.Rows[0]["id"].ToString());
byte[] r = client.UploadData(url, data);
using (var stream = System.IO.File.Create("FilePath"))
{
stream.Write(r,0,r.length);
}
}
Try this. Remember to change the filepath. Since the data you posted is not valid
json. So, I decide to post data this way.
I think it's straight forward, but instead of using WebClient, you can use HttpClient, it's better.
here is the answer HTTP client for downloading -> Download file with WebClient or HttpClient?
comparison between the HTTP client and web client-> Deciding between HttpClient and WebClient
Example Using WebClient
public static void Main(string[] args)
{
string path = #"download.pdf";
// Delete the file if it exists.
if (File.Exists(path))
{
File.Delete(path);
}
var uri = new Uri("https://ewbbackend-preprodpub-http.internal.cleartax.co/gst/v0.1/taxable_entities/1c74ddd2-6383-4f4b-a7a5-007ddd08f9ea/ewaybill/download?print_type=detailed");
WebClient client = new WebClient();
client.Headers[HttpRequestHeader.ContentType] = "application/json";
client.Headers.Add("X-Cleartax-Auth-Token", "b1f57327-96db-4829-97cf-2f3a59a3a548");
client.Encoding = Encoding.UTF8;
var data = UTF8Encoding.UTF8.GetBytes("[\"GLD24449\"]");
byte[] r = client.UploadData(uri, data);
using (var stream = System.IO.File.Create(path))
{
stream.Write(r, 0, r.Length);
}
}
Here is the sample code, don't forget to change the path.
public class Program
{
public static async Task Main(string[] args)
{
string path = #"download.pdf";
// Delete the file if it exists.
if (File.Exists(path))
{
File.Delete(path);
}
var uri = new Uri("https://ewbbackend-preprodpub-http.internal.cleartax.co/gst/v0.1/taxable_entities/1c74ddd2-6383-4f4b-a7a5-007ddd08f9ea/ewaybill/download?print_type=detailed");
HttpClient client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, uri)
{
Content = new StringContent("[\"GLD24449\"]", Encoding.UTF8, "application/json")
};
request.Headers.Add("X-Cleartax-Auth-Token", "b1f57327-96db-4829-97cf-2f3a59a3a548");
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
using (FileStream fs = File.Create(path))
{
await response.Content.CopyToAsync(fs);
}
}
else
{
}
}
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);
}
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);
}
I am currently using the SharePoint Authentication.asmx to create an authentication session from within my C# application. This is all working as expected and I can upload files etc
I also have links to my sharepoint site within my application using:
Process.Start("**/documents/Forms/***"); //URL modified for StackOverflow
The issue I have is that my users are prompted to login from the browser when clicking on a button with my application, which is understandable since the browser doesn't have a session. Is there some way I can share the session I have in my app with the browser?
This is the code I am using to authenticate:
using (SPAuth.Authentication authSvc = new SPAuth.Authentication())
{
authSvc.Url = #"***/_vti_bin/Authentication.asmx"; //URL modified for StackOverflow
authSvc.CookieContainer = new System.Net.CookieContainer();
//set the FBA login information
SPAuth.LoginResult result = authSvc.Login(username, password);
if (result.ErrorCode == SPAuth.LoginErrorCode.NoError)
{
try
{
...
}
catch
{
...
}
}
}
if you can maintain browser object following method might solve your problem.
public void AuthenticateInSharePoint(String url, String login, String password)
{
try
{
var uri = new Uri(url);
var uriBuilder = new UriBuilder();
uriBuilder.Scheme = uri.Scheme;
uriBuilder.Port = uri.Port;
uriBuilder.Host = uri.Host;
uriBuilder.Path = "_forms/default.aspx";
uriBuilder.Query = String.Format("ReturnUrl={0}", HttpUtility.UrlEncode(uri.LocalPath));
var request = (HttpWebRequest)HttpWebRequest.Create(uriBuilder.ToString());
request.ContentType = "application/x-www-form-urlencoded";
request.AllowAutoRedirect = true;
var response = (HttpWebResponse)request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var html = reader.ReadToEnd();
var doc = new HtmlDocument();
doc.LoadHtml(html);
foreach (var node in doc.DocumentNode.Descendants("script").ToList())
node.Remove();
foreach (var node in doc.DocumentNode.Descendants("link").ToList())
node.Remove();
var form = doc.DocumentNode.Descendants("form").FirstOrDefault();
if (form != null)
{
form.Attributes["action"].Value = uriBuilder.ToString();
var script = doc.CreateElement("script");
script.InnerHtml = String.Format(#"
var input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'ctl00$PlaceHolderMain$signInControl$login');
input.value = 'Sign In';
document.forms[0].appendChild(input);
document.getElementById('ctl00_PlaceHolderMain_signInControl_UserName').value=""{0}"";
document.getElementById('ctl00_PlaceHolderMain_signInControl_password').value=""{1}"";
document.forms[0].submit();", login, password);
var body = doc.DocumentNode.Descendants("body").FirstOrDefault();
if (body != null)
body.AppendChild(script);
}
var builder = new StringBuilder();
using (var writer = new StringWriter(builder))
doc.Save(writer);
return Content(builder.ToString(), response.ContentType);
}
}
catch (Exception e)
{
Log.Error(e, "Failed to authenticate user in SharePoint.");
}
}
I'm trying to download a file, from a link that looks like:
www.sample.com/download.php?id=1234231
I don't know which file I'll get from this link.
First I tried webclient.downloadfile(link,path) - but the path I gave as the folder that the file should be in gave me an access denied error.
My problem is that I can't determine the file I'll get.
I've tried something like:
var wreq = (HttpWebRequest)HttpWebRequest.Create(link);
using (var res = (HttpWebResponse) wreq.GetResponse())
{
using (var reader = new StreamReader(res.GetResponseStream()))
{
//get filename Header
var filenameHeader =
res.GetResponseHeader("Content-Disposition")
.Split(';')
.Where(s => s.Contains("filename"))
.ToList()[
0];
var fileName = filenameHeader.Replace(" ", "").Split('=')[1];
//clear fileName
fileName = fileName.Replace(":", "");
using (var writer = new StreamReader(Path.Combine(folderToSave , fileName),FileMode.Create))
{
writer.Write(reader.ReadToEnd());
}
}
}
Isn't there something simpler than that?
Is is there any chance that I will download a file and not get a "Content-Disposition" header?
Last thing, at the moment I'm trying to write the file using a StreamWriter but the resulting file is corrupted. I assume that this is something related to not writing in binary format, but I'm not sure.
I've also checked the "Content-Length" header and it was a different value than the response.GetResponse().ToString().Length, maybe the header is counted it the length as well?
You can extend WebClient class for this
class MyWebClient : WebClient
{
public string FileName { get; private set; }
protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
FileName = Regex.Match(((HttpWebResponse)response).Headers["Content-Disposition"], "filename=(.+?)$").Result("$1");
string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
Regex r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));
FileName = r.Replace(FileName, "-");
return response;
}
}
Usage:
MyWebClient mwc = new MyWebClient();
byte[] bytes = mwc.DownloadData("http://subtitle.co.il//downloadsubtitle.php?id=202500");
File.WriteAllBytes(Path.Combine(folderToSave, mwc.FileName), bytes);