The client needs us to send two files via FTP during the process of synchronizing the General Ledger between Axapta and their own propriatary system.
Once more axaptapedia.com saves the day. This time pointing us to the FtpWebRequest class in the .NET framework inside Dynamics AX. The Axaptapedia page is complete except for one wafer-thin omission... Exception handling.
Let me save your time and eyes and tell you now that it is of the type Exception::CLRError, and I've also converted the Job to a server static function, below and added the necessary permissions. Here comes the science if you wish to continue:
/// http://www.axaptapedia.com/FtpWebRequest
/// Params:
/// _inputFile: "C:/tmpServer/test.xml"
/// _destinationFile: "ftp://123.234.34.45/BD01/test.xml"
/// _user: "user"
/// _password: "pass"
/// _useProxy: false
public client server static str uploadFileFTP(str _inputFile, str _destinationFile,
str _user, str _password,
boolean _useProxy = false)
{
str retVal;
object ftpo;
object ftpResponse;
InteropPermission permI = new InteropPermission(InteropKind::ClrInterop);
FileIOPermission permIO = new FileIOPermission(_inputFile,'r');
Set permissionSet = new Set(Types::Class);
System.Net.FtpWebRequest request;
System.IO.StreamReader reader;
System.IO.Stream requestStream;
System.Byte[] bytes;
System.Net.NetworkCredential credential;
System.String xmlContent;
System.Text.Encoding utf8;
System.Net.FtpWebResponse response;
System.Exception netExcepn;
;
try
{
// Permissions
permissionSet.add(permI);
permissionSet.add(permIO);
CodeAccessPermission::assertMultiple(permissionSet);
// Read file
reader = new System.IO.StreamReader(_inputFile);
utf8 = System.Text.Encoding::get_UTF8();
bytes = utf8.GetBytes( reader.ReadToEnd() );
reader.Close();
// little workaround to get around the casting in .NET
ftpo = System.Net.WebRequest::Create(_destinationFile);
request = ftpo;
credential = new System.Net.NetworkCredential(_user, _password);
request.set_Credentials(credential);
request.set_ContentLength(bytes.get_Length());
request.set_Method("STOR");
if (_useProxy)
{ // "Bypass" a HTTP Proxy (FTP transfer through a proxy causes an exception)
request.set_Proxy( System.Net.GlobalProxySelection::GetEmptyWebProxy() );
}
requestStream = request.GetRequestStream();
requestStream.Write(bytes,0,bytes.get_Length());
requestStream.Close();
ftpResponse = request.GetResponse();
response = ftpResponse;
}
catch (Exception::CLRError)
{
netExcepn = CLRInterop::getLastException();
error(netExcepn.ToString());
}
catch
{ // Error desconocido / Unknown error
error("@SYS83461");
}
if (response)
{
// info(response.get_StatusDescription());
retVal = response.get_StatusDescription();
}
return retVal;
}
A few of my own recommendations- As a stinky consultant that works on the client site, in a bank, wearing a tie that sends you screaming out of the door, I have very limited rights to my machine and I can't install services. I can therefore recommend WarFTP as a standalone executable FTP Server for all of your testing needs. Out of the box it comes as pretty locked down so read the faq when you can't work out why the new user you just created can't use the service.
- Execute on the server. Not only is it going to be faster generating our export file from the General Ledger but we'll have only one source of problems instead of the 'n' client machines out there each with their own firewall or McAfee Fascist settings.
- Use the following snippet to obtain the executing computer's temporary directory: (isRunningOnServer() ? WinAPIServer::getTempPath() :WinAPI::getTempPath()).
Finally this whole exercise was in my case for naught as we later discovered that the client was using Trivial File Transfer Protocol [1] [2]! I think my next post should be on how to execute a batch file from within Axapta to do all of the above but with a special FTP client...
No hay comentarios:
Publicar un comentario