Questo è quello che devo fare, in poche parole:
-
Genera file di fogli di calcolo Excel (programmaticamente).
-
Archivia questi file .xlsx in un percorso a cui possono accedere gli utenti successivamente. Questi file devono essere "su Internet / nel cloud", poiché la maggior parte dei downloader legittimi non sono utenti interni e quindi non si trovano nella rete della nostra azienda)
-
Rendi questi file disponibili all'utente in modo che possano scaricarli tramite un collegamento su una pagina Web.
Questo è quello che ho fatto finora:
Il passaggio 1, la generazione programmatica dei file .xlsx, è completo. Attualmente, tuttavia, questi vengono salvati in una cartella locale sulla macchina su cui viene eseguita l'app (un'app di Winforms che consente all'utente di selezionare i criteri necessari per generare i report utilizzando i dati corretti).
Come per i passaggi 2 e 3, ho creato un progetto Web API (C #, ASP.NET) che presenta una pagina basata sulla logica di routing (il tipo di report, la società per la quale è stato generato il report, come parametri per le date del rapporto convers). Sto visualizzando la pagina appropriata, ma il link di download che sto generando tramite HTML non funziona. A quanto pare, il problema è che la posizione nel progetto web (la cartella App_Data) in cui sto salvando i file .xlsx generati non è accessibile o non viene rappresentata correttamente.
Ho provato "tutto" per far funzionare il collegamento per il download, come si può vedere qui, su StackOverflow , ma mi chiedo se devo fare un passo indietro per considerare di provare qualcosa di fondamentalmente diverso , dato che mi sento come se stessi sbattendo la testa contro il muro con questo approccio.
A partire da ora, sto solo testando file di fogli di calcolo molto semplici che l'app Web API genera dinamicamente (non quelli generati dall'app Winform). Potrei:
- Utilizza lo stesso codice nell'app Web API che sto utilizzando nell'app Winforms per generare questi file .xlsx.
- Invia i file .xlsx dall'app Winforms all'app dell'API Web, ma non so come farlo. Dove posso inviarli? Sicuramente non direttamente nella cartella App_Data dell'app Web API, ma come / dove?
Il modo in cui i metodi REST funzionano ora è che ho un metodo GET per l'URL REST che cerca il file generato corrispondente; se esiste già (il file è stato precedentemente generato), lo rende in una pagina. Se il file non esiste ancora, il metodo GET chiama il metodo POST, che genera il file; quindi, il file esiste e il file appena generato viene visualizzato su una nuova pagina:
[RoutePrefix("api/fillrate")]
public class FillRateController : ApiController
{
[Route("{unit}/{begindate}")]
// URL would be something like "http://localhost:52194/api/fillrate/Gramps/201509"
public HttpResponseMessage Get(string unit, string begindate)
{
string _unit = unit;
string _begindate = begindate;
string appDataFolder =
HttpContext.Current.Server.MapPath("~/App_Data/");
string fillRatefillRateByDistByCustFilename =
string.Format("fillRateByDistByCust_{0}_{1}.html", _unit, _begindate);
string fillRateFullPath = Path.Combine(appDataFolder,
fillRatefillRateByDistByCustFilename);
// If report has been generated, open it from its file (in AppData
folder);
// otherwise, generate it now; in this way, any date range for this
report can be requested
if (!File.Exists(fillRateFullPath))
{
Post(unit, begindate);
}
var HtmlToDisplay = File.ReadAllText(fillRateFullPath);
return new HttpResponseMessage()
{
Content = new StringContent(
HtmlToDisplay,
Encoding.UTF8,
"text/html"
)
};
}
[Route("{unit}/{begindate}")]
[HttpPost]
public void Post(string unit, string begindate)
{
string _unit = unit;
string _begindate = String.Format("{0}01",
HyphenizeYYYYMM(begindate));
string _enddate = GetEndOfMonthFor(_begindate);
string appDataFolder =
HttpContext.Current.Server.MapPath("~/App_Data/");
DataTable dtFillRateResults = null;
List<FillRateByDistributorByCustomer>
_fillRateByDistributorByCustomerList = null;
List<FillRateByDCByLocation> _fillRateByDCByLocationList = null;
List<string> _members = SQLDBHelper.GetMemberStringList();
try
{
foreach (String _memberId in _members)
{
dtFillRateResults =
SQLDBHelper.ExecuteSQLReturnDataTable(
. . .
);
. . .
// Create minimalistic spreadsheet file for now
var fillRateByDistByCustHtmlStr =
ConvertFillRateByDistributorByCustomer(_fillRateByDistributorByCustomerList,
unit, begindate);
string fillRatefillRateByDistByCustFilename =
string.Format("fillRateByDistByCust_{0}_{1}.html", _unit, begindate);
string fullFillRateByDistByCustPath =
Path.Combine(appDataFolder, fillRatefillRateByDistByCustFilename);
File.WriteAllText(fullFillRateByDistByCustPath,
fillRateByDistByCustHtmlStr);
}
catch (Exception ex)
{
. . .
}
}
Queste pagine renderizzate hanno un link per il download da cui è possibile scaricare il file .xlsx (se solo funziona, piuttosto che fingere l'ignoranza della cartella App_Data).
Quindi questo è un design / approccio sensato, o qualcos'altro è indicato? Sicuramente questo non è un requisito unico che non è mai stato risolto prima, quindi qual è il "metodo preferito" o l'approccio canonico per farlo?
UPDATE
Quello che ho intenzione di fare, e sono nel mezzo dell'attuazione, è questo:
1) Memorizza i file in un database (dall'app Winforms)
2) Nell'app API Web ASP.NET, generare un set di collegamenti su una pagina, uno per ciascun report salvato
3) Questi collegamenti avranno ciascuno un href ancora un altro indirizzo REST, che risponderà leggendo il file dal database e scaricandolo