c# Ftpclient not working and python can retrive the data - python-3.x

I'm trying to use the c# library to download a file from an FTP. The code we are using is straight forward.
static void Main(string[] args)
{
Connect(true, true, true);
}
private static void Connect(bool keepAlive, bool useBinary, bool usePassive)
{
string RemoteFtpPath = "ftp://ftp.xxxx.ac.uk/incoming/testExtractCSVcoursesContacts.csv";
const string Username = "anonymous";
const string Password = "anonymous#xxxx.ac.uk";
var request = (FtpWebRequest)WebRequest.Create(new Uri(RemoteFtpPath));
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = keepAlive;
request.UsePassive = usePassive;
request.UseBinary = useBinary;
request.Credentials = new NetworkCredential(Username, Password);
request.Timeout = 30000;
try
{
var response = (FtpWebResponse)request.GetResponse();
var responseStream = response.GetResponseStream();
var reader = new StreamReader(responseStream);
var fileString = reader.ReadToEnd();
Console.WriteLine(
$"Success! keepAlive={keepAlive}, useBinary={useBinary}, usePassive={usePassive} Length={fileString.Length}");
reader.Close();
response.Close();
}
catch (Exception e)
{
Console.WriteLine(
$"Failed! keepAlive={keepAlive}, useBinary={useBinary}, usePassive={usePassive}, message={e.Message}");
}
}
`
we also tried to set passive = true with identical results.
When we run it, using wireshark we are getting : Wireshark log c#
Now we tried the same with Python and it's working just fine:
import urllib.request
data = urllib.request.urlretrieve('path')
print(data)
the wireshark log looks quite different:
So tried different things, but not able to sort this out.

Some ftp servers don't support OPTS UTF8 but still transmit file names in UTF8. (Note that 'OPTs UTF8' is NOT required by the FTP Internationalization Standard, although supporting UTF8 file names is.) The .NET Ftp classes will use the default code page if they don't get an OK response to OPTS UTF8... It's unfortunate that MS didn't provide some way to use UTF8 anyway, since this leaves you unable to transmit international file names to and from otherwise UTF8-compliant servers.
The issue is sorted after using a different library as FtpWebRequest doesn't support it

Related

Upload BASE64 binary file to SharePoint document library

I have been looking for ways to upload BASE64 binary files days and I am stuck.
First of all a do not know how to convert BASE64 binary file to array buffer, blob, ... Everything is about BASE64 string but I have BASE64 binary file.
Do you have any solution?
You need to convert this Base64 string to byte array. C# Programming provide several approaches to do this without trouble. Following Upload large files sample SharePoint Add-in and Convert.FromBase64String(String) Method, both at Microsoft Docs, the final code that meet your requirements will be like this:
//This approach is useful for short files, less than 2Mb:
public void UploadFileContentFromBase64(ClientContext ctx, string libraryName, string fileName, string base64Str)
{
Web web = ctx.Web;
// Ensure that target library exists. Create if it is missing.
if (!LibraryExists(ctx, web, libraryName))
{
CreateLibrary(ctx, web, libraryName);
}
FileCreationInformation newFile = new FileCreationInformation();
// The next line of code causes an exception to be thrown for files larger than 2 MB.
newFile.Content = Convert.FromBase64String(base64Str);
newFile.Url = fileName;
// Get instances to the given library.
List docs = web.Lists.GetByTitle(libraryName);
// Add file to the library.
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
ctx.Load(uploadFile);
ctx.ExecuteQuery();
}
//This other approach provides you to Upload large files, more than 2Mb:
public void UploadDocumentContentStreamFromBase64(ClientContext ctx, string libraryName, string fileName, string base64Str)
{
Web web = ctx.Web;
// Ensure that the target library exists. Create it if it is missing.
if (!LibraryExists(ctx, web, libraryName))
{
CreateLibrary(ctx, web, libraryName);
}
byte[] fileContent = Convert.FromBase64String(base64Str);
using (MemoryStream memStream = new MemoryStream(fileContent))
{
FileCreationInformation flciNewFile = new FileCreationInformation();
// This is the key difference for the first case - using ContentStream property
flciNewFile.ContentStream = memStream;
flciNewFile.Url = fileName;
flciNewFile.Overwrite = true;
List docs = web.Lists.GetByTitle(libraryName);
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(flciNewFile);
ctx.Load(uploadFile);
ctx.ExecuteQuery();
}
}

Selenium WebDriverIE Sending single character as Lowecase

I have recently changed from Windows 7 to a Windows 10 machine and, when running a previous Cucumber unit test pack that was working fine, I am now experiencing issues with SendKeys - which is causing all tests to fail unexpectedly. SendKeys seems to be sending the first character of a string as a ToLower().
Example:
string User = "ANALYSTUSER"
I am sending keys as:
SendKeys(User) / SendKeys(User.ToUpper())
and it is always populating the field as aNALYSTUSER!
I have rolled back the NuGet Package/driver version through the latest 10 versions and the issue still occurs. (I have also tried the 64-bit driver.)
Selenium.Support
Selenium.WebDriver
Selenium.WebDriver.IEDriver
Does anybody have an idea as to what may cause this and what can be tried here?
Perhaps the issue relates to your website client side JavaScript, it will change the entered value, I have created a sample using the following code, it works well on my side. You could have a try:
private const string URL = #"https://www.bing.com/";
private const string IE_DRIVER_PATH = #"E:\webdriver\IEDriverServer_x64_3.14.0"; // where the Selenium IE webdriver EXE is.
static void Main(string[] args)
{
InternetExplorerOptions opts = new InternetExplorerOptions() { IntroduceInstabilityByIgnoringProtectedModeSettings = true};
using (var driver = new InternetExplorerDriver(IE_DRIVER_PATH, opts))
{
driver.Navigate().GoToUrl("https://www.bing.com/");
var element = driver.FindElementById("sb_form_q");
element.SendKeys("WEBDRIVER");
Console.ReadKey();
}
}
Besides, you could also try to execute the script to enter a value, code as below.
private const string URL = #"https://www.bing.com/";
private const string IE_DRIVER_PATH = #"E:\webdriver\IEDriverServer_x64_3.14.0"; // where the Selenium IE webdriver EXE is.
static void Main(string[] args)
{
InternetExplorerOptions opts = new InternetExplorerOptions() { IntroduceInstabilityByIgnoringProtectedModeSettings = true};
using (var driver = new InternetExplorerDriver(IE_DRIVER_PATH, opts))
{
driver.Navigate().GoToUrl("https://www.bing.com/");
var element = driver.FindElementById("sb_form_q");
var script = "document.getElementById('sb_form_q').value = 'webdriver';";
IJavaScriptExecutor jse = (IJavaScriptExecutor)driver;
jse.ExecuteScript(script, element);
//element.SendKeys("webdriver");
element.SendKeys(Keys.Enter);
}
}

FTP return 150 openingdate on Win2012 server

The following code works perfectly fine from my own machine (Win7 ISS7) but when I move it to a virtual server running IIS8 on a datacentre then I get the return code 150 (openingdata). I can access the ftp site via IE on this server. Is this a coding issue or configuration. Any help is greatly appreciated.
I've also tried changing UsePassive, UseBinary, no caching, to no effect and place it on an azure machine but to no avail.
private List<string> Browse()
{
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(m_Url);
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
result.Add("Timeout = " + request.Timeout.ToString());
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential(m_Username, m_Password);
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
if (m_Proxy != null)
{
request.Proxy = m_Proxy;
}
bool started = false;
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
using (StreamReader reader = new StreamReader(responseStream))
{
string line = reader.ReadLine();
while (line != null)
{
result.Add(line);
line = reader.ReadLine();
}
}
}
return result;
}
Turned out it was a program error
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(m_Url);
should have been
FtpWebRequest request = (FtpWebRequest)*Ftp*WebRequest.Create(m_Url);

ServiceStack: httpReq.GetRawBody() is empty

I have a global requestfilter from where i want to log all http traffic using log4net - company restriction. Problem is that the InputStream is always lenght = 0. The soap envelope is desezerialized correctly and execution of service is succesfull, but inputstream is unavailable after first serialization. Is this wrong approach, if i want to log all ingoing and outgoing http traffic? What should i do to accomplish this? I do not want to log the deserialized requestDto.
this.RequestFilters.Add((httpReq, httpResp, requestDto) =>
{
LogManager.LogFactory.GetLogger(this.GetType()).Info(httpReq.GetRawBody());
});
Error seems to occur in type ServiceStack.WebHost.Endpoints.Support.SoapHandler in method, where using statement closes stream without buffering it:
protected static Message GetRequestMessage(Stream inputStream, MessageVersion msgVersion)
{
using (var sr = new StreamReader(inputStream))
{
var requestXml = sr.ReadToEnd();
var doc = new XmlDocument();
doc.LoadXml(requestXml);
var msg = Message.CreateMessage(new XmlNodeReader(doc), int.MaxValue,
msgVersion);
return msg;
}
}
When i try to access GetRawBody on type ServiceStack.WebHost.Endpoints.Extensions the following logic is executed:
public string GetRawBody()
{
if (bufferedStream != null)
{
return bufferedStream.ToArray().FromUtf8Bytes();
}
using (var reader = new StreamReader(InputStream))
{
return reader.ReadToEnd();
}
}
Here I would expect the inpustream to be buffered, since it Inputstreaem is no longer available (lenght = 0).
Isn't this a bug?
Have you seen Request Logger or IRequiresRequestStream. These might help provide some insight on logging requests. Also, I don't believe InputStream would have a length on GET requests.

Downloading bulk files from sharepoint library

I want to download the files from a sharepoint document library through code as there are thousand of files in the document library.
I am thinking of creating console application, which I will run on sharepoint server and download files. Is this approach correct or, there is some other efficient way to do this.
Any help with code will be highly appreciated.
Like SigarDave said, it's perfectly possible to achieve this without writing a single line of code. But if you really want to code the solution for this, it's something like:
static void Main(string[] args)
{
// Change to the URL of your site
using (var site = new SPSite("http://MySite"))
using (var web = site.OpenWeb())
{
var list = web.Lists["MyDocumentLibrary"]; // Get the library
foreach (SPListItem item in list.Items)
{
if (item.File != null)
{
// Concat strings to get the absolute URL
// to pass to an WebClient object.
var fileUrl = string.Format("{0}/{1}", site.Url, item.File.Url);
var result = DownloadFile(fileUrl, "C:\\FilesFromMyLibrary\\", item.File.Name);
Console.WriteLine(result ? "Downloaded \"{0}\"" : "Error on \"{0}\"", item.File.Name);
}
}
}
Console.ReadKey();
}
private static bool DownloadFile(string url, string dest, string fileName)
{
var client = new WebClient();
// Change the credentials to the user that has the necessary permissions on the
// library
client.Credentials = new NetworkCredential("Username", "Password", "Domain");
var bytes = client.DownloadData(url);
try
{
using (var file = File.Create(dest + fileName))
{
file.Write(bytes, 0, bytes.Length); // Write file to disk
return true;
}
}
catch (Exception)
{
return false;
}
}
another way without using any scripts is by opening the document library using IE then in the ribbon you can click on Open in File Explorer where you can then drag and drop the files right on your desktop!

Resources