Siebel COM Data Control File Transfer - c#

Get the attachment from Siebel using COM Data Control.
SiebelBusObjectInterfaces.SiebelDataControl sblDataControl = new SiebelBusObjectInterfaces.SiebelDataControl();
bool success = sblDataControl.Login("host=\"siebel.TCPIP.None.None://bla bla bla /EAIObjMgr_enu\"", "karephul", getPassword());
string errorCode = sblDataControl.GetLastErrCode() + " " + sblDataControl.GetLastErrText();
SiebelBusObjectInterfaces.SiebelBusObject oBO;
SiebelBusObjectInterfaces.SiebelBusComp serviceRequest;
SiebelBusObjectInterfaces.SiebelBusComp actionAttachment;
oBO = sblDataControl.GetBusObject("Action");
actionAttachment = oBO.GetBusComp("Action Attachment");
success = actionAttachment.ActivateField("Activity Id");
success = actionAttachment.ActivateField("ActivityFileName");
success = actionAttachment.ClearToQuery();
success = actionAttachment.SetSearchSpec("Activity Id", "3-QOUKDD"); // hard code for now.
success = actionAttachment.SetSearchSpec("ActivityFileExt", "txt");
success = actionAttachment.ExecuteQuery(1); // ForwardOnly = 1, I guess;
if (actionAttachment.FirstRecord())
{
string fileName = actionAttachment.GetFieldValue("ActivityFileName");
string fileLoc = actionAttachment.InvokeMethod("GetFile", "ActivityFileName");
}
This below piece of code gets the appropriate file and keep it in temp folder of the server and gives me fully qualified path.
string fileLoc = actionAttachment.InvokeMethod("GetFile", "ActivityFileName");
Is there a way I can get the file to my local machine ?
Context:
This code is written in C# and we run this code on client side which does not have access to temp directory of the server.
Thanks
Karephul

Since your are connecting via datacontrol to http, this is equivalent to connecting to the thin client. If you connect via a dedicated client, you can save the file directly onto your system.
The above 3 solutions would work, but I suggest you can send the file over by email, if attachment size is not a problem.

After talking to some guys working on Siebel, I found that with COM API's I cannot get the file to the local machine.
Options:
1. Make the temp folder public and get the file.
2. Ask your Siebel team to expose a webservice to get the file.
3. Ask your Siebel team to provide REST type link to download file.

Related

How to save file on server

I have .net framework web forms that needs to save pdf. But I can't save that to wanted location because application is ran through IISExpres and I cant acces my project directories. This is on localhost but will eventually be on server.
This is code that accepts svg string from javascript.
[WebMethod()]
public static List<string> sendEmail(string svgStr)
{
List<string> ret = new List<string>();
string savePath = Path.Combine("some path", "file.pdf");
var options = new PdfSaveOptions();
//this converts svg string to pdf
//instead of path, there can be passed memory stream provider
//which is extended from Aspose.Html.IO.ICreateStreamProvider
//but i dont know how to use this like memory stream
Converter.ConvertSVG(svgStr, ".", options, savePath);
ret.Add("proslo je");
return ret;
}
Edit: I managed to get the pdf to memory stream and use it later. Thanks for help.
If the path is accessible via the internet not at a lower level than the application that is running it you just need to map the web path to the underlying server path.
var filePath = HttpContext.Current.Server.MapPath("/download/" +filename);
This will take the path from the root of the website.
You just need to provide the required permissions on the target folder for the account running the application. A guide on how to do so can be found here: https://www.online-tech-tips.com/computer-tips/set-file-folder-permissions-windows/

C# - Checking several IP adresses with several download methods

I am new to this site so I apologise in advance if I made any formatting errors. Let me know if further clarification is needed.
I am currently working on a program in C# which aims at downloading files from several http or ftp sources.
I want it to go through several IP addresses and then check if several methods could download a known file successful. If one of these methods could download the file successfully it should go to the next IP and do the same thing again.
So far I am using a foreach loop that runs through an array containing the IP and creating a folder named "IPxx" and a FTP and HTTP URI because I do not know in advance which IP needs a FTP or HTTP address:
string[] ipArray = new string[4];
ipArray[0]= "xxx.xxx.xxx.xx";
ipArray[1]= "xxx.xxx.xxx.xx";
ipArray[2]= "xxx.xxx.xxx.xx";
ipArray[3]= "xxx.xxx.xxx.xx";
foreach(string ip in ipArray )
{
string ipXx = "IP" + ip.Substring(ip.Length-2);
string ipOrdner = folder + #"\" + ipXx;
Directory.CreateDirectory(ipOrdner);
string ftpAddr= "ftp://" + ip;
string httpAddr= "http://"+ip;
//DownloadTestMethod(httpAddr, ipFolder);
//DownloadTestMethod2(ftpAddr, ipFolder);
//DownloadTestMethod3(htppAddr, ipFolder);
}
So far so good, everything up to this level is working as expected.
However I struggle as soon as I need to go through several Download Methods and check if I can download the file successfully and if not it should go to the next DownloadMethod and try the same.
I came up with following DownloadTestMethod:
public static void DownloadTestMethod(string httpAddr, string ipFolder)
{
string fileName = "test_10k.bin";
string downloadpath = httpAddr + "/" + fileName;
// I want it to check if the http site is online/working
WebRequest request = WebRequest.Create(downloadpath);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response != null)
{
WebClient webClient = new WebClient();
webClient.Proxy.Credentials=CredentialCache.DefaultCredentials;
webClient.DownloadFile(downloadpath, ipFolder + #"\" + fileName);
}
}
It is working for a successfully downloaded file, however I seem to get "stuck" in this method if the method cannot downloaded the requested file.
In this case I want it to jump to the next DownloadMethod and check again until all methods are checked.
Furthermore, if the program went through every IP and it could not download anytrhing, I want it to send an automated email. I know how to implement the EmailMethod but once again I struggle with flow control.
I am an absolute beginner and have no idea how to go from here to get my desired flow.
You might want to look at Task Parallel Library and in particular, its WhenAll() method.
Under it, you might want to look at error handling for the case that any of your methods return error / raise exception.
https://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx

FileUpload does not let me to save

I have a confusing problem. I'm trying to use FileUpload. The following code works well locally:
var postedFile = uploader.PostedFile;
var fileName = Path.GetFileName(postedFile.FileName);
var extension = Path.GetExtension(fileName);
var newFile = Guid.NewGuid() + extension;
var imageFilePath = Path.Combine(this.Server.MapPath("~/ProductImages"), newFile);
uploader.SaveAs(imageFilePath);
But when I publish my code to my server in internet the following exception occurs:
Could not find a part of the path [...]
When I change uploader.SaveAs(imageFilePath); to uploader.SaveAs(imageFilePath.Replace(this.Request.ServerVariables["APPL_PHYSICAL_PATH"], "..\\"));, this exception occurs:
The SaveAs method is configured to require a rooted path, and the path [..] is not rooted.
Would any one tell me how to use an Uploader? And how I can solve this problem?
With thanks
There is no problem in your code. When you run an application over the a web server, web server manged by a user in OS.(for examle nobody for enginx or Application Pool group in IIS).
You should set permission for folder that you want save the data. this my be done in your hosting file manager panel or via direct access to OS.
The problem is that local accounts aren't valid on remote resources on active directory - you need to connect as ComputerName$ or Anonymous depending on the type of local identity that you are using.
I was able to upload on debug mode but not on published site, so that might help you Mohammad.
Are you sure the folder ProductImages exists on the server?
You can try to call
Directory.CreateDirectory(this.Server.MapPath("~/ProductImages"))
before saving the file. It will create the directory if it doesn't exists or do nothing if it exists.
I finally solved the problem by setting the permission on the folder. I set the write permission on "Application pool group" for that folder and now I can upload any file there, by my app.
Thanks
Try this one.. for uploading and insert the values in database..
string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);
FileUpload1.SaveAs(Server.MapPath("~/" + filename));
Stream str = FileUpload1.PostedFile.InputStream;
con.Open();
SqlCommand cmds = new SqlCommand("insert into datas(name,path,types,pricing)values(#name,#path,#types,#pricing)", con);
cmds.Parameters.AddWithValue("#name",d);
cmds.Parameters.AddWithValue("#path", filename);
cmds.Parameters.AddWithValue("#types", RadioButton1.Text);
cmds.Parameters.AddWithValue("#pricing", "FineGrained");
cmds.ExecuteNonQuery();
Response.Write("<script>alert('successfully uploaded');</script>");

w3wp.exe (NETWORK SERVICE user) is locking a newly created file and preventing access to it

I have a Web application. It sends a series of images to the server (no problem there) and then uses code from this tutorial to create a PowerPoint presentation. The presentation is saved in a directory on the web server and the URL is returned to the user.
However, the file is still in use and attempting to access it generates a 500.0 error in IIS 7.5.
If I open the task manager and kill the w3wp.exe process that belongs to the NETWORK SERVICE user everything works as intended (the file can be downloaded and viewed). I also have another w3wp process belonging to DefaultAppPool, but it doesn't seem to cause a problem.
I'm new to this .Net coding, so it is very possible I forgot to close something down in code. Any ideas?
Edit: This is the method that creates a series of png's from image data that is encoded into a string. It uses a Guid to create a unique bit of a directory path, and checks to make sure it doesn't exist and then creates the directory and places the images there.
It looks like the offending method is this one:
So the offending method is this one:
public void createImages(List<String> imageStrings)
{
UTF8Encoding encoding = new UTF8Encoding();
Decoder decoder = encoding.GetDecoder();
Guid id = Guid.NewGuid();
String idString = id.ToString().Substring(0, 8);
while (Directory.Exists(imageStorageRoot + idString))
{
id = Guid.NewGuid();
idString = id.ToString().Substring(0, 8);
}
String imageDirectoryPath = imageStorageRoot + idString + "\\";
DirectoryInfo imagePathInfo = Directory.CreateDirectory(imageDirectoryPath);
for (int i = 0; i < imageStrings.Count; i++)
{
String imageString = imageStrings[i];
Byte[] binary = Convert.FromBase64String(imageString);
using (FileStream stream = new FileStream(imageDirectoryPath + idString + i.ToString() + ".png", FileMode.Create))
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(binary);
}
}
}
}
Edit 2: If there is a better to about doing things please let me know. I am trying to learn here!
Edit 3: So upon further examination, I can comment out all this code. In fact, the second instance of w3wp.exe starts up as soon as a browser hits the website. I am now wondering if this might have something else to do with our stack? Its a Flex app, that uses WebOrb for remoting to some C# classes.
Does anyone know why this second open instance of w3wp.exe (owned by NETWORK SERVICE) would prevent the file from opening properly? Is there some way to get it release it's hold on the file in question?
Make sure you've closed the file after using it (better yet put the code that accesses your files in using statements). Post some code if you need help figuring out where the issue is.
The sample looks good. Did you deviate from the code structure?
using (Package pptPackage =
Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite))
{
// your code goes inside there
}
If your code does contain the using statement you should be fine. If not add a Dispose call to your Package object when you are done or you will leave the file open for a long time until (possibly) the finalizer will kill it.

Downloading all files using FTP and C#

What is the best way to download all files in a remote directory using C# and FTP and save them to a local directory?
Thanks.
downloading all files in a specific folder seems to be an easy task. However, there are some issues which has to be solved. To name a few:
How to get list of files (System.Net.FtpWebRequest gives you unparsed list and directory list format is not standardized in any RFC)
What if remote directory has both files and subdirectories. Do we have to dive into the subdirs and download it's content?
What if some of the remote files already exist on the local computer? Should they be overwritten? Skipped? Should we overwrite older files only?
What if the local file is not writable? Should the whole transfer fail? Should we skip the file and continue to the next?
How to handle files on a remote disk which are unreadable because we don’t have sufficient access rights?
How are the symlinks, hard links and junction points handled? Links can easily be used to create an infinite recursive directory tree structure. Consider folder A with subfolder B which in fact is not the real folder but the *nix hard link pointing back to folder A. The naive approach will end in an application which never ends (at least if nobody manage to pull the plug).
Decent third party FTP component should have a method for handling those issues. Following code uses our Rebex FTP for .NET.
using (Ftp client = new Ftp())
{
// connect and login to the FTP site
client.Connect("mirror.aarnet.edu.au");
client.Login("anonymous", "my#password");
// download all files
client.GetFiles(
"/pub/fedora/linux/development/i386/os/EFI/*",
"c:\\temp\\download",
FtpBatchTransferOptions.Recursive,
FtpActionOnExistingFiles.OverwriteAll
);
client.Disconnect();
}
The code is taken from my blogpost available at blog.rebex.net. The blogpost also references a sample which shows how ask the user how to handle each problem (e.g. Overwrite/Overwrite older/Skip/Skip all).
Using C# FtpWebRequest and FtpWebReponse, you can use the following recursion (make sure the folder strings terminate in '\'):
public void GetAllDirectoriesAndFiles(string getFolder, string putFolder)
{
List<string> dirIitems = DirectoryListing(getFolder);
foreach (var item in dirIitems)
{
if ( item.Contains('.') )
{
GetFile(getFolder + item, putFolder + item);
}
else
{
var subDirPut = new DirectoryInfo(putFolder + "\\" + item);
subDirPut.Create();
GetAllDirectoriesAndFiles(getFolder + item + "\\", subDirPut.FullName + "\\");
}
}
}
The "item.Contains('.')" is a bit primitive, but has worked for my purposes. Post a comment if you need an example of the methods:
GetFile(string getFileAndPath, string putFileAndPath)
or
DirectoryListing(getFolder)
For FTP protocol you can use FtpWebRequest class from .NET framework. Though it does not have any explicit support for recursive file operations (including downloads). You have to implement the recursion yourself:
List the remote directory
Iterate the entries, downloading files and recursing into subdirectories (listing them again, etc.)
Tricky part is to identify files from subdirectories. There's no way to do that in a portable way with the FtpWebRequest. The FtpWebRequest unfortunately does not support the MLSD command, which is the only portable way to retrieve directory listing with file attributes in FTP protocol. See also Checking if object on FTP server is file or directory.
Your options are:
Do an operation on a file name that is certain to fail for file and succeeds for directories (or vice versa). I.e. you can try to download the "name". If that succeeds, it's a file, if that fails, it's a directory. But that can become a performance problem, when you have a large number of entries.
You may be lucky and in your specific case, you can tell a file from a directory by a file name (i.e. all your files have an extension, while subdirectories do not)
You use a long directory listing (LIST command = ListDirectoryDetails method) and try to parse a server-specific listing. Many FTP servers use *nix-style listing, where you identify a directory by the d at the very beginning of the entry. But many servers use a different format. The following example uses this approach (assuming the *nix format)
void DownloadFtpDirectory(
string url, NetworkCredential credentials, string localPath)
{
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);
listRequest.UsePassive = true;
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
listRequest.Credentials = credentials;
List<string> lines = new List<string>();
using (WebResponse listResponse = listRequest.GetResponse())
using (Stream listStream = listResponse.GetResponseStream())
using (StreamReader listReader = new StreamReader(listStream))
{
while (!listReader.EndOfStream)
{
lines.Add(listReader.ReadLine());
}
}
foreach (string line in lines)
{
string[] tokens =
line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
string name = tokens[8];
string permissions = tokens[0];
string localFilePath = Path.Combine(localPath, name);
string fileUrl = url + name;
if (permissions[0] == 'd')
{
Directory.CreateDirectory(localFilePath);
DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath);
}
else
{
var downloadRequest = (FtpWebRequest)WebRequest.Create(fileUrl);
downloadRequest.UsePassive = true;
downloadRequest.UseBinary = true;
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
downloadRequest.Credentials = credentials;
var response = downloadRequest.GetResponse();
using (Stream ftpStream = response.GetResponseStream())
using (Stream fileStream = File.Create(localFilePath))
{
ftpStream.CopyTo(fileStream);
}
}
}
}
The url must be like:
ftp://example.com/ or
ftp://example.com/path/
Or use 3rd party library that supports recursive downloads.
For example with WinSCP .NET assembly you can download whole directory with a single call to Session.GetFiles:
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "example.com",
UserName = "user",
Password = "mypassword",
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Download files
session.GetFiles("/home/user/*", #"d:\download\").Check();
}
Internally, WinSCP uses the MLSD command, if supported by the server. If not, it uses the LIST command and supports dozens of different listing formats.
(I'm the author of WinSCP)
You could use System.Net.WebClient.DownloadFile(), which supports FTP. MSDN Details here
You can use FTPClient from laedit.net. It's under Apache license and easy to use.
It use FtpWebRequest :
first you need to use WebRequestMethods.Ftp.ListDirectoryDetails to get the detail of all the list of the folder
for each files you need to use WebRequestMethods.Ftp.DownloadFile to download it to a local folder

Categories