I am uploading files to dropbox using the following code.
I am using the nuget package Dropbox.Api and getting the exception System.Threading.Tasks.TaskCanceledException("A task was canceled.")
From this SO Question it appears to be a timeout issue.
So how do I modify the following code to set the timeout.
public async Task<FileMetadata> UploadFileToDropBox(string fileToUpload, string folder)
{
DropboxClient client = new DropboxClient(GetAccessToken());
using (var mem = new MemoryStream(File.ReadAllBytes(fileToUpload)))
{
string filename = Path.GetFileName(fileToUpload);
try
{
string megapath = GetFullFolderPath(folder);
string megapathWithFile = Path.Combine(megapath, Path.GetFileName(Path.GetFileName(filename))).Replace("\\", "/");
var updated = client.Files.UploadAsync(megapathWithFile, WriteMode.Overwrite.Instance, body: mem);
await updated;
return updated.Result;
}
catch (Exception ex)
{
return null;
}
}
}
Try creating and initializing the client like this:
var config = new DropboxClientConfig();
config.HttpClient.Timeout = new TimeSpan(hr, min, sec); // choose values
var client = DropboxClient(GetAccessToken(), config);
Reference:
http://dropbox.github.io/dropbox-sdk-dotnet/html/M_Dropbox_Api_DropboxClient__ctor_1.htm
One more thing to keep in mind is UploadAsync will not work for files larger than 150MB as per documentation. One will have to use UploadSessionStartAsync based implementation for it. I was making the mistake without realizing it and it took ages for me to fish the problem out.
Related
Recently I have migrated my code from .NetFramework to .NetCore 3.1.
While doing this I got stuck in a place where MoveFolder functionality handled.
Earlier the code was like below.
public void MoveS3Folder(string sourceBucket, string targetBucket, string sourceFolder, string targetFolder)
{
sourceFolder = sourceFolder.Replace('/', '\\');
targetFolder = targetFolder.Replace('/', '\\');
using (var client = AwsObjectCreator.GetAmzonS3())
{
var source = new S3DirectoryInfo(client, sourceBucket, sourceFolder);
S3DirectoryInfo target = new S3DirectoryInfo(client, targetBucket, targetFolder);
if (!target.Exists)
{
target.Create();
}
try
{
source.MoveTo(target);
}
catch (System.IO.IOException e)
{
if (e.Message.Equals("File already exists", StringComparison.OrdinalIgnoreCase))
{
target = new S3DirectoryInfo(client, targetBucket, targetFolder + "\\" + DateTime.Now.ToString("MM-dd-yyyy hh-mm-ss"));
target.Create();
source.MoveTo(target);
}
}
}
}
Since, earlier we were using AWSSDK.S3 Sdk package which has S3DirectoryInfo class, with the help of this we had achieved the goal.
Now, I would be looking for a similar solution w.r.t AWSSDKCore.S3.
Things I have tried so far:
https://www.derpturkey.com/copy-a-folder-in-amazons3-using-the-c-api/
https://docs.aws.amazon.com/AmazonS3/latest/dev/CopyingObjectUsingNetSDK.html
I understood the concept of copying data from the above articles but not worked on my end.
Error I am getting - “The specified key does not exist”
It will be appreciable, if anyone could help !
Instead of var client = AwsObjectCreator.GetAmzonS3() ----Wrong way
Create the client like this
IAmazonS3 client = new AmazonS3Client(awsAccessKey, awsSecretKey, RegionEndpoint.USWest2);
I wrote a program using CSOM to upload documents to SharePoint and insert metadata to the properties. once a while(like every 3 months) the SharePoint server gets busy or we reset IIS or any other communication problem that it may have, we get "The operation has timed out" error on clientContext.ExecuteQuery(). To resolve the issue I wrote an extension method for ExecuteQuery to try every 10 seconds for 5 times to connect to the server and execute the query. My code works in the Dev and QA environment without any problem but in Prod, when it fails the first time with timeout error, in the second attempt, it only uploads the document but it doesn't update the properties and all the properties are empty in the library. It doesn't return any error as result of ExecteQuery() but It seems from the two requests in the batch witch are uploading the file and updating the properties, it just does uploading and I don't know what happens to the properties. It kinda removes that from the batch in the second attempt!
I used both upload methods docs.RootFolder.Files.Add and File.SaveBinaryDirect in different parts of my code but I copy just one of them here so you can see what I have in my code.
I appreciate your help.
public static void ExecuteSharePointQuery(ClientContext context)
{
int cnt = 0;
bool isExecute = false;
while (cnt < 5)
{
try
{
context.ExecuteQuery();
isExecute = true;
break;
}
catch (Exception ex)
{
cnt++;
Logger.Error(string.Format("Communication attempt with SharePoint failed. Attempt {0}", cnt));
Logger.Error(ex.Message);
Thread.Sleep(10000);
if (cnt == 5 && isExecute == false)
{
Logger.Error(string.Format("Couldn't execute the query in SharePoint."));
Logger.Error(ex.Message);
throw;
}
}
}
}
public static void UploadSPFileWithProperties(string siteURL, string listTitle, FieldMapper item)
{
Logger.Info(string.Format("Uploading to SharePoint: {0}", item.pdfPath));
using (ClientContext clientContext = new ClientContext(siteURL))
{
using (FileStream fs = new FileStream(item.pdfPath, FileMode.Open))
{
try
{
FileCreationInformation fileCreationInformation = new FileCreationInformation();
fileCreationInformation.ContentStream = fs;
fileCreationInformation.Url = Path.GetFileName(item.pdfPath);
fileCreationInformation.Overwrite = true;
List docs = clientContext.Web.Lists.GetByTitle(listTitle);
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(fileCreationInformation);
uploadFile.CheckOut();
//Update the metadata
ListItem listItem = uploadFile.ListItemAllFields;
//Set field values on item
foreach (List<string> list in item.fieldMappings)
{
if (list[FieldMapper.SP_VALUE_INDEX] != null)
{
TrySet(ref listItem, list[FieldMapper.SP_FIELD_NAME_INDEX], (FieldType)Enum.Parse(typeof(FieldType), list[FieldMapper.SP_TYPE_INDEX]), list[FieldMapper.SP_VALUE_INDEX]);
}
}
listItem.Update();
uploadFile.CheckIn(string.Empty, CheckinType.OverwriteCheckIn);
SharePointUtilities.ExecuteSharePointQuery(clientContext);
}
catch (Exception ex)
{
}
}
}
}
There's too many possible reasons for me to really comment on a solution, especially considering it's only on the prod environment.
What I can say is that it's probably easiest to keep a reference to the last uploaded file. If your code fails then check if the last file has been uploaded correctly.
Side note: I'm not sure if this is relevant but if it's a large file you want to upload it in slices.
Im working on a simple WPF application that has the sole purpose of using Renci SSH.net library to get the working directory of a SshClient and further passing it to a SftpClient.
I cant seem to change the directory using sftpClient.ChangeDirectory by using the absolute path returned from a RunCommand ("pwd"). I know for certain that the path does exist since the SshClient returns it, but maybe there is something i am doing wrong, or there is a bug? Either way, here is my code:
public static string ssh_host,
ssh_username,
ssh_password,
workingDirectory;
public MainWindow()
{
InitializeComponent();
ssh_host = "XXXXXXXXXX";
ssh_username = "XXXXXXXXXX";
ssh_password = "XXXXXXXXXX";
StartSSH();
}
private static void StartSSH()
{
using (var client = new SshClient(ssh_host, ssh_username, ssh_password))
{
try
{
client.Connect();
if (client.IsConnected)
{
Console.WriteLine("Client connected");
SshCommand getSSHWorkingDirectory = client.RunCommand("pwd");
workingDirectory = getSSHWorkingDirectory.Result;
Console.WriteLine("SSH working directory = " + workingDirectory);
// RESULT: SSH working directory = /customers/5/7/9/domain.com/httpd.private
using (var sftpClient = new SftpClient(ssh_host, ssh_username, ssh_password))
{
sftpClient.Connect();
if (sftpClient.IsConnected)
{
Console.WriteLine("SFTP working directory = " + sftpClient.WorkingDirectory);
// RESULT: SFTP working directory = /customers/5/7/9/domain.com/httpd.www <- NOTE httpd.www
sftpClient.ChangeDirectory(workingDirectory);
// ERROR: Renci.SshNet.Common.SftpPathNotFoundException: No such file
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
As you can see, there is thrown an exception when trying to change the directory i got using the SshClient RunCommand result.
My question is: Why is ChangeDirectory failing to execute, and how would i forward solving this issue in a proper manner?
Any help is much appreciated.
The problem was that the string returned from the RunCommand had whitespaces and all I had to do was this:
workingDirectory = getSSHWorkingDirectory.Result.Trim();
I have tried for two days to solve this issue and when I first posted this I got it to work 2 minutes later.
When I run this code:
var stream = File.OpenRead(#"C:\tmp\PdfToTest.PDF");
var latestVersion = GhostscriptVersionInfo.GetLastInstalledVersion();
rasterizer = new GhostscriptRasterizer();
rasterizer.Open(stream, latestVersion, false);
I am getting this error
An exception of type 'Ghostscript.NET.GhostscriptAPICallException' occurred in Ghostscript.NET.dll but was not handled in user code
Additional information: An error occured when call to 'gsapi_init_with_args' is made: -15
The error is in this line:
rasterizer.Open(stream, latestVersion, false);
Anyone could point me what it is causing this to happen?
I am running this in local machine. Installed the Ghostscript on Package manager console. Everything seems to be right, but it simple doesn't work.
-15 is a 'rangecheck' error. There should be considerable extra backchannel information which might give some useful details. However since you are not using Ghostscript directly I can't tell you where it might be going.
You should put the PDF file you are using as input somewhere public at least so we can look at it.
Ideally you should reproduce the problem with Ghostscript itself, from the command line, but in any event you must supply the configuration information (ie what settings you have used). The version of Ghostscript (and whether its 32 or 64 bit) would also be useful information.
I'm afraid there's nothing much anyone can do with what you've given us to go on.
This is my working example.
So I call the method ResizePDF(string filePath) and give the file path including extension (eg. C:\tmp\file.pdf) as parameter.
The method returns the memoryStream with the resized file that I can use to do whatever.
There are some work to do around it, however it is working so far.
internal MemoryStream ResizePDF(string filePath)
{
string inputFilePath = String.Format(#"{0}", filePath);
GhostscriptPipedOutput gsPipedOutput = new GhostscriptPipedOutput();
string outputPipeHandle = "%handle%" + int.Parse(gsPipedOutput.ClientHandle).ToString("X2");
MemoryStream memStream = null;
using (GhostscriptProcessor processor = new GhostscriptProcessor())
{
try
{
processor.Process(GetGsArgs(inputFile, outputPipeHandle));
byte[] rawDocumentData = gsPipedOutput.Data;
memStream = new MemoryStream(rawDocumentData);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
gsPipedOutput.Dispose();
gsPipedOutput = null;
}
}
return memStream;
}
private string[] GetGsArgs(string inputFilePath, string outputFilePath)
{
List<string> switches = new List<string>();
switches.Add("-empty");
switches.Add("-dQUIET");
switches.Add("-dSAFER");
switches.Add("-dBATCH");
switches.Add("-dNOPAUSE");
switches.Add("-dNOPROMPT");
switches.Add("-dPDFSETTINGS=/ebook");
switches.Add("-sDEVICE=pdfwrite");
switches.Add("-sPAPERSIZE=a4");
switches.Add("-sOutputFile=" + outputPipeHandle);
switches.Add("-f");
switches.Add(inputFilePath);
return switches.ToArray();
}
Thanks you all.
I am using SharpSVN dll with my Visual Studio 2010 to get the latest revision number so I can version my project using this number. I tried this piece of code below but it gives me error saying:
Can't determine the user's config path
I don't even understand what that means. All I want to do is provide the svn link, my credentials like username and password and get the latest revision number.
Here is the code I tried so far:
using(SvnClient client = new SvnClient())
{
//client.LoadConfiguration(Path.Combine(Path.GetTempPath(), "Svn"), true);
Collection<SvnLogEventArgs> list;
client.Authentication.DefaultCredentials = new NetworkCredential("john.locke", "s7y5543a!!");
SvnLogArgs la = new SvnLogArgs();
client.GetLog(new Uri("https://100.10.20.12/svn/P2713888/trunk/src/"), la, out list);
string sRevisionNumber = string.Empty;
int iRevisionNumber = 0;
foreach(SvnLogEventArgs a in list)
{
if (Convert.ToInt32(a.Revision) > iRevisionNumber)
{
iRevisionNumber = Convert.ToInt32(a.Revision);
}
}
RevisionNumber.Text = iRevisionNumber.ToString();
}
other ways to get the revision number may also be selected as answer.
I had this problem as well-- needing to find/set properties on the SvnClient before use. Here's what I ended up using. Try using this method instead of just instantiating your client object-- it will auto-create a config folder if it doesn't already exist:
private SvnClient GetClient()
{
SvnClient client = new SvnClient();
// Note: Settings creds up here is optional
// client.Authentication.DefaultCredentials = _creds;
string configPath = Path.Combine(Path.GetTempPath(), "sharpsvn");
if (!Directory.Exists(configPath))
{
Directory.CreateDirectory(configPath);
}
client.LoadConfiguration(configPath, true);
return client;
}
Alternately, if you want to minimize File IO checking to see if the directory exists, you can try LoadConfiguration, and only create and reassign the directory if that call failed, but just checking each time is simpler.
At any rate, you can then get the latest revision number for a location using the following code:
public long GetLatestRevisionNumber(Uri svnPath)
{
using (SvnClient client = GetClient())
{
SvnInfoEventArgs info;
client.GetInfo(svnPath, out info);
return info.LastChangeRevision;
}
}