|
|
#1 |
|
Участник
|
AX 2012 EP. Как скачать файл. Решение.
Добрый день, товарищи!
Предлагаю вашему вниманию решение проблемы закачки файлов с портала. Это может пригодится, когда на портале формируется некий отчет, например в формате Excel, кладется в папку на сервере и его необходимо передать клиенту через браузер. Должно работать так же, как работает стандартный диалог просмотра прикрепленных файлов. Буду описывать свое решение. Конструктивная критика и предложения по улучшению механизма принимаются )) |
|
|
|
| За это сообщение автора поблагодарили: Ganna (1). | |
|
|
#2 |
|
Участник
|
Итак, начинаем готовить.
1. Пишем "ядро" загрузчика. Я дописал еще один метод в класс EPDocuGet, взяв за основу один из существующих методов. X++: #define.BUFFER_SIZE(4096) static void runDownloadFile(Filename fileName) { IISResponse response = new IISResponse(); BinData binData; int fileOffset; str headerFileName; ; headerFileName = System.IO.Path::GetFileName(fileName); headerFileName = strReplace(headerFileName, ';', '_'); headerFileName = strReplace(headerFileName, ' ', '_'); headerFileName = System.Web.HttpUtility::UrlEncode(headerFileName); response.clear(); response.contentType('application/Octet-Stream'); response.addHeader('Content-Disposition', 'attachment;filename="' + headerFileName + '"'); binData = new BinData(); fileOffset = 0; new FileIOPermission(fileName, 'r').assert(); while (true) { // BP Deviation Documented if (!binData.loadFile(fileName, fileOffset, #BUFFER_SIZE)) { break; } fileOffset += #BUFFER_SIZE; EPDocuGet::writeToResponse(response, binData.getData()); } } |
|
|
|
|
#3 |
|
Участник
|
2. Пишем специальную aspx-страницу для вызова загрузчика, например, downloadFile.aspx со следующим содержимым:
Код: <%@ Page Language="C#" Trace="false" %>
<%@ Assembly Name="Microsoft.Dynamics.Framework.Portal, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" %>
<%@ Assembly Name="Microsoft.Dynamics.Framework.Data.Ax, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" %>
<%@ Assembly Name="Microsoft.Dynamics.Framework.BusinessConnector, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" %>
<%@ Assembly Name="Microsoft.Dynamics.Framework.BusinessConnector.Proxy, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" %>
<%@ Assembly Name="Microsoft.Dynamics.Framework.Metadata.AX, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null" %>
<%@ Import Namespace="Microsoft.Dynamics.Framework.Portal" %>
<%@ Import Namespace="Microsoft.Dynamics.Framework.Portal.UI" %>
<%@ Import Namespace="Microsoft.Dynamics.AX.Framework.Portal.Data" %>
<%@ Import Namespace="Microsoft.Dynamics.Framework.BusinessConnector.Proxy" %>
<%@ Import Namespace="Microsoft.Dynamics.Framework.BusinessConnector.Session" %>
<%@ Import Namespace="Microsoft.Dynamics.Framework.BusinessConnector.Adapter" %>
<%@ Import Namespace="Microsoft.Dynamics.AX.Framework.Services.Client" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
AxSharepointWebSession session = null;
string fileName = this.Request.QueryString["file"];
try
{
session = SessionHelper.Instance.GetSharepointSession();
if (session != null)
{
session.AxaptaAdapter.CallStaticClassMethod("EPDocuGet", "runDownloadFile", fileName);
Response.Flush();
}
}
catch (System.Exception)
{
// Current design is to not display errors to the user
// Errors are stored in the event log for review by the site operator
}
finally
{
if (session != null)
{
SessionHelper.Instance.ReleaseSharepointSession(session);
}
}
}
</script>Как видно, при загрузке этой страницы будет происходить получение имени файла из параметров запроса и вызов созданного в п. 1 метода с передачей ему имени файла. 3. Создаем в АОТ ссылку на эту страницу. Web\Web Menu ITems\URLs Назовем ее DownloadFile. В свойстве URL пишем: _layouts/ep/downloadFile.aspx |
|
|
|
|
#4 |
|
Участник
|
4. Теперь все готово к тестированию.
Создаем файл для загрузки и кладем его на сервер, например, в c:\temp\test.xls Будем его скачивать. 5. Далее нам понадобится VisualStudio. Создаем веб-контрол для веб-парт страницы. Кладем туда кнопку и в обработчике нажатия кнопки пишем код: Код: AxUrlMenuItem getFileUrl = new AxUrlMenuItem("DownloadFile");
getFileUrl.ExtraParams.Add("file", "c:\\temp\\test.xls");
DialogHelper.Navigate(getFileUrl, this);Код: protected void WebPart_ActionMenuItemClicked(object sender, ActionMenuItemEventArgs e)
{
string fileName = string.Empty;
if (e.MenuItem.MenuItemAOTName == "WayBill")
{
fileName = (string)this.RunDatasetMethod("makeWayBill"); // вызов метода, который формирует отчет и кладет файл отчета в папку на сервере
}
if (!string.IsNullOrEmpty(fileName))
{
AxUrlMenuItem getFileUrl = new AxUrlMenuItem("DownloadFile");
getFileUrl.ExtraParams.Add("file", fileName);
DialogHelper.Navigate(getFileUrl, this);
}
}
private object RunDatasetMethod(string methodName, params object[] paramList)
{
object res = null;
try
{
if (paramList.Length > 0)
{
res = this.AxDataSource1.GetDataSet().DataSetRun.AxaptaObjectAdapter.Call(methodName, paramList);
}
else
{
res = this.AxDataSource1.GetDataSet().DataSetRun.AxaptaObjectAdapter.Call(methodName);
}
}
catch (System.Exception ex)
{
AxExceptionCategory exceptionCategory;
if (!AxControlExceptionHandler.TryHandleException(this, ex, out exceptionCategory))
{
// Throw the fatal exception
throw;
}
}
return res;
}Спасибо за внимание! |
|
|
|
| За это сообщение автора поблагодарили: MikeR (5), gl00mie (5), (1). | |
|
|
#5 |
|
Возьми свет!!!
|
перенес в четверку. что то не то творится с разрешениями файлов.
__________________
Axapta 3.0 sp 5 Oracle ![]() Я могу взорвать вам мозг!!! |
|
|
|
|
#6 |
|
Участник
|
Боюсь в 4ке это не будет работать (
Там используется более прозаический метод закачки файлов: X++: static void redirectFile(FileName _name) { websession().redirectURL(strfmt('%1_layouts/EP/TEMP/%2', webSession().siteUrl(), _name)); } |
|
|
|
|
#7 |
|
Возьми свет!!!
|
Цитата:
X++: #define.BUFFER_SIZE(4096) #File client static void runReport(Common callerRecord, IISResponse response) { Query query = new Query(); QueryBuildDataSource qbds; QueryRun queryRun; EPSendDocument document; BinData binData; str fileName; int fileOffset; DictTable table = new DictTable(callerRecord.TableId); str tempFileName; boolean emptyReport; ; if (WebLet::hasTableAccess(callerRecord.TableId)) { qbds = query.addDataSource(callerRecord.TableId); if (callerRecord && callerRecord.TableId != tablenum(DocuRef)) { // Requery the record to test record level security qbds.addRange(table.fieldName2Id('RecId')).value(SysQuery::value(callerRecord.RecId)); query.recordLevelSecurity(true); queryRun = new QueryRun(query); if (queryRun.next()) { document = new EPSendDocument(callerRecord); tempFileName = WinAPI::getTempFilename(WinAPI::getTempPath(), 'DAX'); document.parmOriginal(true); document.parmFileName(tempFileName); // Make document will run the report and send it to a PDF file with // the path specified in tempFileName document.makeDocument(); fileName = document.parmDocumentTitle(); // remove all ';' from the filename. These are treated as delimiters by Ie fileName = strReplace(fileName, ';', '_'); emptyReport = (WinAPI::fileSize(document.parmFileName()) == 0); response.clear(); response.contentType('application/Octet-Stream'); binData = new BinData(); if (emptyReport) { response.addHeader('Content-Disposition', 'attachment;filename="' + fileName + #txt + '"'); response.writeTxt(strfmt([EMAIL="'@SYS58533'"]'@SYS58533'[/EMAIL], fileName)); } else { response.addHeader('Content-Disposition', 'attachment;filename="' + fileName + #pdf + '"'); // Loop over the stored file and chunk it down to the client fileOffset = 0; while(true) { // BP Deviation Documented if (!binData.loadFile(tempFileName, fileOffset, #BUFFER_SIZE)) { break; } fileOffset += #BUFFER_SIZE; response.binaryWrite(binData.getVariant()); } } binData = null; WinAPI::deleteFile(tempFileName); } } } }
__________________
Axapta 3.0 sp 5 Oracle ![]() Я могу взорвать вам мозг!!! |
|
|
|
|
#8 |
|
Молодой, подающий надежды
|
Цитата:
X++: switch (file.Extension.ToLower()) { case "xlsx": HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; break; default: HttpContext.Current.Response.ContentType = "application/octet-stream"; break; } |
|
|
|
| За это сообщение автора поблагодарили: gl00mie (2). | |
| Теги |
| ax2009, ax2012, enterprise portal, mime types, законченный пример |
|
|
|