I am trying to create an SSIS package that gets a folder tree structure from a remote SQL DB and recreates that structure in a document library in Sharepoint.
I tried to (hard) code a Script Task to create just one folder but I'm getting this error:
http://img856.imageshack.us/img856/1386/helpel.png
After running only a part of this script:
Microsoft.Sharepoint.Client.dll
Microsoft.Sharepoint.Client.Runtime.dll
public void Main()
{
ClientContext clientContext = new ClientContext("http://spdemo.example.com/");
clientContext.Credentials = new System.Net.NetworkCredential("admin", "password", "SPDEMO");
Web rootWeb = clientContext.Web;
Dts.TaskResult = (int)ScriptResults.Success;
}
I've scoured the internet for solutions, but haven't found something that works for me.
So basically i need to find out how to:
create a folder
populate it with sub-folders
Copy files in bitestreams from SQL to Sharepoint, all in SSIS
Thanks in advance!
Regards,
Vlad Ardelean
After some research I found out that in order to reference a DLL in a SSIS Script Task it first has to be strong named
Instead, I have found an easier way to create folders and upload files:
public void CreateFolder(string url)
{
HttpWebRequest request = (System.Net.HttpWebRequest)HttpWebRequest.Create(url);
request.Credentials = new NetworkCredential(user, pass);
request.Method = "MKCOL";
HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
response.Close();
}
public void UploadDocument(byte[] file, string destinationName)
{
byte[] buffer = file;
WebRequest request = WebRequest.Create(destinationName);
request.Credentials = new System.Net.NetworkCredential(user, pass);
request.Method = "PUT";
request.ContentLength = buffer.Length;
BinaryWriter writer = new BinaryWriter(request.GetRequestStream());
writer.Write(buffer, 0, buffer.Length);
writer.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
response.Close();
}
url : represents the url path of the folder you want to create
http://spsite.host.com/DocLib/FolderToCreate
destinationName: path + document name
http://spsite.host.com/DocLib/FolderToCreate/DocToCreate.docx
Did you try running your code from a stand-alone windows application written in C# in Visual Studio?
If I get errors in SSIS, my preference is to test that code thoroughly in Visual Studio and then port it to a script task in SSIS.
If you haven't done folder creation and file copy to SharePoint, the below links might help.
Create a folder - http://thingsthatshouldbeeasy.blogspot.in/2009/09/how-to-add-folder-to-sharepoint-list.html
You can do the create folder step recursively untill you have created the destination tree structure.
Copy Files - http://msdn.microsoft.com/en-us/library/ms454491.aspx, http://msdn.microsoft.com/en-us/library/ms470176.aspx
I dont understand what you mean by copy file in bitestreams from SQL. If you want to read binary data from SQLServer via ADO.Net use System.Data.SqlDbType.VarBinary
Read the data from SQL server to a stream and write to a temp file, copy that temp file from local to SP. Or you may even write the data in a stream to SP directly without a temp file.
Related
I would like to download a file from a FTP and directly POST to a REST URL without having to save in a temp folder, which I am currently doing. Works great, but not what I want to do. When I take a file directly from the FTP, the File.OpenRead takes not only the FTP path
ftp://xxxx.xxxxxx.xxx/
but it adds the project path
C://myProject/ProjectName
in front of it, thus causing a
The filename, directory name, or volume label syntax is incorrect.
Where am I going wrong?
using(var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/octet-stream");
using(var filestream = File.OpenRead(FTP_Path + FTP_filename))
using(var requestStream = client.OpenWrite(new Uri(fileUploadUrl), "POST"))
{
filestream.CopyTo(requestStream);
}
}
We recently switched our ftp site at work from ftp://address to https://ftp.address and now my application that retrieves files is unable to download files with expected content.
I previously used FtpWebRequest and it has been working for many years.
I am now trying to use WebClient and it downloads a file but it is not the text file I need. Instead, the contents of the file turns out to be some HTML.
Previous that worked:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(getAppSetting("URI") + getAppSetting("FilePath") + args[0].ToString());
request.Method = WebRequestMethods.Ftp.DownloadFile;
setCredentials(request);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Changed code to handle https:
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
WebClient request = new WebClient();
setCredentials(request);
string file = request.DownloadString(getAppSetting("URI") + getAppSetting("FilePath") + args[0].ToString());
The result is a file that is downloaded but it contains HTML. I expect to have the contents of the file on the website I am pulling from.
After a couple of weeks of research, I finally found out what I needed to do and the answer was quite simple. I found out that our new website uses SSH so I installed SSH.Net via my nugent package to Visual Studio, and added "using Renci.SshNet;". I used the following code to download the file to my local drive:
using (SftpClient sftp = new SftpClient("ftp.website.com", 22,"username", "password")
{
sftp.Connect();
if (sftp.IsConnected)
{
using (Filestream fs = new FileStream("Output.txt", FileMode.Create))
{
sftp.DownloadFile("/file/Client/Input.txt", fs);
}
}
sftp.Disconnect();
}
This works perfectly. My file no longer downloads as an HTML file and I get my desired output. I hope this saves someone else a lot of time.
I have a windows service application that needs to download pdf files from different public web sites and save them locally to a folder on the server
I tried to use System.Net.WebClient to perform the download like this
client = new WebClient();
client.DownloadFile(new Uri(fileLink, UriKind.Absolute), destination);
destination is the full path and name to the folder where I need to save the file to. example: \server-name\downloads\file123.pdf
fileLink is the url to the pdf file
One of the links I am trying to save is: https://www.wvmmis.com/WV%20Medicaid%20Provider%20SanctionedExclusion/WV%20Medicaid%20Exclusions%20-%20June%202016.pdf
The code works but the file that is saved is corrupted and cannot be opened by Acrobat reader or any pdf reader.
If you click the link above and do save as and save the page locally to a pdf, then you can open it fine. So the problem is not that the pdf is really corrupted, but WebClient is not saving it right.
Is there any configuration I can do to the WebClient that causes it to save the file correctly, or is there another way to do it that does save it right ?
Thank you
I wrote something similar long time ago
try
{
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
string originalFileName = response.ResponseUri.AbsolutePath.Substring(response.ResponseUri.AbsolutePath.LastIndexOf("/") + 1);
Stream streamWithFileBody = response.GetResponseStream();
using (Stream output = File.OpenWrite(#"C:\MyPath\" + originalFileName))
{
streamWithFileBody.CopyTo(output);
}
Console.WriteLine("Downloded : " + originalFileName);
}
catch (Exception ex)
{
Console.WriteLine("Unable to Download : " + ex.ToString());
}
After trying all the examples that I found online without luck, I finally figured out a way to do this. I am posting my answer here in case someone else runs into the same problem.
I used selenium FireFoxDriver to navigate to the page that contains the link, then I find the link and click it. I created a profile in firefox to download the file type pdf directly instead of opening it.
FirefoxDriver driver = new FirefoxDriver(myProfile);
driver.Navigate().GoToUrl(pageUrl);
driver.FindElement(By.LinkText(linkText)).Click();
You can also find the link by href or id too, but in my case I needed to find it by text.
I am trying to build a list of all files on a ftp server.
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(remote);
request.Credentials = new NetworkCredential(userName, passWord);
request.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
List<string> files = new List<string>();
// Build List of all files
string line = streamReader.ReadLine();
while (!string.IsNullOrWhiteSpace(line))
{
files.Add(line);
line = streamReader.ReadLine();
}
streamReader.Close();
Now, the problem is, whe i use this list with the broken/incomplete file to download all the files with a Webclient, the code breaks when trying to download the incomplete file...
The remote server returned an error: (550) File unavailable (e.g.,
file not found, no access)
How can i skip these files when building the list?
I the catch of the exeption i just added a "ignore" when the exeptions was "The remote server returned an error: (550) File unavailable (e.g., file not found, no access)"
This way i dont get the error and the file gets downloaded just fine when its complete on the ftp server.
I have a page where users can upload files. I don't save the files - I use a stream and upload them to a 3rd party server. I do store the path in a database.
I now need to upload those files to a different server. So, I have a path in a database like:
J:\Projects\Commercial\somedoc.docx
and I now need to allow users to select and upload the file at that location to another server. I can't use the path in a control - as you cannot set the value of such a control.
I am going to display a list of the file paths on a .aspx page for a user to select which files they need to upload (again, but to a different server).
How can I upload the file when all I have is a string which is the path?
Normally I would have:
HttpFileCollection hfc = Request.Files;
HttpPostedFile hpf = hfc[0];
using (Stream fx = hpf.InputStream)
{
//send the stream to a remote server here
}
but I don't have the posted file to work with, all I have is a path.
" need to upload (again, but to a different server) ". means you have to copy from one server to another.
So i think you have to use FTP copy.
The below code may help you. The code is not tested. Please try
string CompleteDPath = "";
CompleteDPath = "ftp://1234.1234.12.13/Projects/Commercial";
string UName = "";
string PWD = "";
UName = "Administrator";
PWD = "12345";
WebRequest reqObj = WebRequest.Create(CompleteDPath + "somedoc.docx");
reqObj.Method = WebRequestMethods.Ftp.UploadFile;
reqObj.Credentials = new NetworkCredential(UName, PWD);
FileStream streamObj = System.IO.File.OpenRead(physical path + "somedoc.docx");
byte[] buffer = new byte[streamObj.Length + 1];
streamObj.Read(buffer, 0, buffer.Length);
streamObj.Close();
streamObj = null;
reqObj.GetRequestStream().Write(buffer, 0, buffer.Length);
reqObj = null;
As per your comment...
Yes, they have uploaded a load of different files to Server A and now, a few weeks later, need to see a list of the files they uploaded to Server A and upload them to Server B. (It is not possible for me to copy from Server A to Server B as I don't have access to them
As you have already stated, you cannot pre-select a file on a users computer - which is completely correct, as otherwise it would be a massive security hole.
If you have no ability to directly transfer the files from the Server A to Server B, then you simply have no other choice than to request the user to select those files again.
Maybe a way forward would be to list all the files they have uploaded, and provide individual upload controls for them to populate.
Be aware that there is normally a limit to the maximum "request" size that IIS will accept (which can easily be reached if uploading multiple files in a single go). This limit can be raised through configuration, but a higher value increases the resource loading on the server