Newsgroup: it.comp.lang.delphi
Titolo: D2005 classe System.Net.WebClient ???

per eseguire il download di un file , nel msdn trovo il metodo
DownloaFile , che usa System.Net.WebClient
in D2005 digitando nella sezione uses non trovo la classe WebClient ,
nella classe System.Net ha solo Sockets
in Vb.Net invece si puo' dichiarare Imports System.Net.WebClient;
mi pare strano che questa classe non sia presente in Delphi, o che sia
presente con altro nome.
che ne pensate, grazie Maurizio 

 presente con altro nome.
Tutte le classi disponibili e fruibili da 
VB.NET
 o C# sono a totale 
disposizione anche a Delphi.NET: è una delle fondamentali prerogative 
del framework.
La classe a cui fai riferimento, *WebClient*, è contenuta nel namespace 
"System.Net", pertanto dovrai dichiarare questo namespace nella clausola 
USES e potrai accedere al tipo per crearne istanze, richiamarne metodi e 
così via.
Ciao,
   Marco.
-- 
Marco «Alka» Breveglieri	
http://www.marco.breveglieri.name
  «bvmcnxsjlkhròhyeq, potrei scrivere a questo punto,
   se mi addormentassi sui tasti» (Daniele Luttazzi)

>   Marco.
ho dichiarato Syste.Net nelle uses, ed ora posso dichiarare
procedure TWebForm5.Button10_Click(sender: System.Object; e:
System.EventArgs);
var myClient: WebClient;
begin
 //myClient.Create;
end;
ma se digito il punto dopo myClient.
non ottengo alcun metodo
se scrivo myClient.Create ottento cannot create constructors...
eppure la classe WebClient la riconosce.
ciao Maurizio

 se scrivo myClient.Create ottento cannot create constructors...
La forma corretta è
   myClient := WebClient.Create;
Sei sicuro di aver importato tutti i riferimenti necessari (System.dll)?
Infine, vedo che stai cercando di usare quella classe all'interno del 
codice di una Web Form: a cosa ti servirebbe?


> codice di una Web Form: a cosa ti servirebbe?
sembra che si fosse inceppato l'editor Delphi, riavviato funziona
quello che vorei fare e' usare il metodo downloadfile per scaricare dal
sever Web al pc locale un file; pero' solleva eccesione
System.UnauthorizedAccessException: Accesso al percorso
"C:\WINDOWS\system32\Libretto 2005.pdf" negato, ma non cambia
impostando un path non di sistema (es: nomefilelocale:='D.\'+'Libretto 
2005.pdf')
procedure TWebForm5.Button10_Click(sender: System.Object; e:
System.EventArgs);
var myClient:WebClient;
    nomeuri,nomefileremoto,nomefilelocale:string;
begin
 myClient.=WebClient.Create;
 nomefileremoto:='htpp:\\<nomesito>\Volantino\';
 nomefilelocale:='Libretto 2005.pdf';
 nomeuri:=nomefileremoto+nomefilelocale;
 myClient.DownloadFile(nomeuri,nomefilelocale);
end;
ciao Maurizio

 sever Web al pc locale un file; pero' solleva eccesione
Immaginavo quasi che l'utilizzo fosse questo.
La classe che stai utilizzando serve a scaricare, da un'applicazione, un 
file dal Web, e non viceversa.
Per consentire ad un utente di scaricare un file attraverso una WebForm 
devi utilizzare i metodi dell'oggetto /Response/ di tipo *HttpResponse* 
restituendo sullo stream il file desiderato, dopo aver modificato 
opportunamente la proprietà /ContentType/ al tipo MIME del file 
restituito ed eventualmente prelevato da una cartella del web server 
usando le tante classi che popolano il namespace "System.IO".


> usando le tante classi che popolano il namespace "System.IO".
dopo vari tentativi ed inutili ricerche , ho trovato su About.com
sembrerebbe idoneo , ho incluso System.IO ma solleva eccezione eseguendo
System.Array.GetUpperBound di oggetto non inizializzato. (riporto sotto il 
codice).
ho anche cambiato  gli Int64 in Int32.
ma array e' un metodo della classe System, possibile che non sia 
inizializzato ?
grazie Maurizio
procedure TWebForm5.Button10_Click(sender: System.Object; e: 
System.EventArgs);
var FileToDownload,Path:String;
begin
 Path:=Server.MapPath('\Test_Delphi\Volantino\');
 FileToDownload := Path+'Libretto 03.pdf';
 DownloadFile(FileToDownload,'LocalTest.txt') ;
end;
procedure TwebForm5.DownloadFile(const FilePath : String; const FileName : 
String =''; const ContentType : String = '') ;
   type
     TStringArray = array of string;
   var
     DownloadFileName : string;
     fi : FileInfo;
     StartPos, FileSize, EndPos : System.Int64;
     Range : string;
     StartEnd : TStringArray;
   begin
     If Not System.IO.File.Exists(FilePath) Then Exit;
     StartPos := 0;
     fi := FileInfo.Create(FilePath) ;
     FileSize := fi.Length;
     EndPos := FileSize;
     HttpContext.Current.Response.Clear() ;
     HttpContext.Current.Response.ClearHeaders() ;
     HttpContext.Current.Response.ClearContent() ;
     Range := HttpContext.Current.Request.Headers['Range'];
     If Assigned(Range) AND (Range <> '') Then
     Begin
       StartEnd := Range.Substring(Range.LastIndexOf('=') + 1).Split(['-']) 
;
       If Not (StartEnd[0] = '') Then
         StartPos := Convert.ToInt64(StartEnd[0]) ;
     End;
**********************************
-----> eseguendo If (System.Array(StartEnd)......
solleva eccezione, riferimento a oggeto non impostato su istanza di oggetto
(direi che l'oggetto non e' stato creato)
     If (System.Array(StartEnd).GetUpperBound(0) >= 1) And (Not (StartEnd[1] 
= '')) Then
       EndPos := Convert.ToInt64(StartEnd[0])
     Else
       EndPos := FileSize - StartPos;
     If EndPos > FileSize Then EndPos := FileSize - StartPos;
     HttpContext.Current.Response.StatusCode := 206;
     HttpContext.Current.Response.StatusDescription := 'Partial Content';
     HttpContext.Current.Response.AppendHeader('Content-Range', 'bytes ' + 
StartPos.ToString + '-' + EndPos.ToString + '/' + FileSize.ToString) ;
   If Not (ContentType = '') And (StartPos = 0) Then
   Begin
     HttpContext.Current.Response.ContentType := ContentType;
   End;
   If FileName = '' Then
     DownloadFileName := fi.Name
   else
     DownloadFileName := FileName;
   HttpContext.Current.Response.AppendHeader('Content-disposition', 
'attachment; filename=' + DownloadFileName) ;
   HttpContext.Current.Response.WriteFile(FilePath, StartPos, EndPos) ;
   HttpContext.Current.Response.&End;
End; 

 inizializzato ?
System non è una classe, è un "namespace", identifica cioè un insieme di 
classi; in Delphi, è trattato alla stregua di una unit nonostante segua 
la notazione puntata, possibile peraltro anche in Win32.
Array è una classe del namespace /System/.
Credo che tu debba reperire un po' di documentazione riguardo il .NET 
Framework e leggere la Guida in linea di Delphi per il linguaggio che 
stai utilizzando.
Tralasciando parte del codice che hai postato (troppo vasto per poter 
essere analizzando punto per punto), ti posto la porzione significativa 
di ciò che ho scritto io per una problematica simile.
Per ottenere il download, ho codificato una pagina ad hoc a cui passo un 
ID che rappresenta l'identificatore del file da scaricare; il percorso 
viene prelevato dal database assieme al ContentType e ad altre 
informazioni per essere poi restituito al browser; questo processo viene 
eseguito al caricamento della pagina (ho ridefinito il metodo /OnLoad/ 
della pagina stessa con *override*).
Segue il codice che effettua la restituzione vera e propria del file:
   // Reperimento info sul file
   // ...
   // Restituzione del file come attachment
   fi := FileInfo.Create(Server.MapPath(
    ConfigurationSettings.AppSettings['FilePath'] + fileName));
   if fi.Exists then
   begin
     Response.ContentType := contentType;
     Response.AppendHeader('Content-Disposition',
      System.String.Format('Attachment; filename="{0}"', fi.Name));
     Response.WriteFile(fi.FullName);
     Response.&End;
   end
   // Altre operazioni correlate
   // ...
Spero possa esserti utile. :-)


> Spero possa esserti utile. :-)
ci mancherebbe, e' sempre utile cio' che scrivi !
grazie della disponibilita'.
ciao Maurizio
^^^^
procedure TWebForm5.Button11_Click(sender: System.Object; e:
System.EventArgs);
var Nome,FullPath: String;
begin
  FullPath:=Server.MapPath('/<nomesito>/Foto/Volantino/Libretto 05.pdf');
  Nome:=Path.GetFileName(FullPath);
  Response.AppendHeader('content-disposition','attachment; filename='+Nome);
  Response.ContentType:='Application/x-msdownload';
  Response.WriteFile(FullPath);
  Response.&End;
end; 

 Apri / Salva / Annulla.
Il ContentType va impostato in base al tipo di file che deve essere 
scaricato; apparentemente, quello che hai trovato potrebbe andare bene 
per file eseguibili generici, ma non sarebbe adatto ad esempio per 
immagini JPEG, file PDF e così via...
Ad ogni formato o estensione, il suo Content Type. ;-)


Ad ogni formato o estensione, il suo Content Type. ;-)
Ciao,
volevo completare la routine scritta da Marco con quella che uso io dove 
evidezio il reperimento del content-type:
procedure Download(nomefile: string);
var Resp : HttpResponse;
    TheFile : FileInfo;
    ContentType : TObject;
    Header : string;
begin
  Resp:=HttpContext.Current.Response;
  TheFile:=FileInfo.Create(nomefile);
  // reperimento del content-type dal reggistro di sistema
  try;
    ContentType:=Registry.ClassesRoot.OpenSubKey
(TheFile.Extension).GetValue('Content Type', 'application\octet-stream');
  except;
    ContentType:='application\octet-stream';
  end;
  // il resto della procedura č uguale a quella proposta
  Resp.ContentType:=ContentType.ToString;
  Header:=System.String.Format('Attachment; filename={0}', TheFile.Name);
  Resp.AppendHeader('Content-Disposition', Header);
  Resp.WriteFile(TheFile.FullName);
  Resp.&End;
end;
--- posted by geoForum on 
http://www.delphiedintorni.it

 evidezio il reperimento del content-type [...]
La mia routine era purtroppo volutamente limitata poichè la tipologia di 
file viene definita attraverso una tabella personalizzata di decodifica. :-)
Adesso, con la tua implementazione aggiuntiva che interroga il Registro, 
cosa si può chiedere di più?? ;-)


[cut] 
molto interessante :)
ovviamente legge le estensioni registrate sul server,
quindi secondo me potrebbe essere utile, essendo il
content-type un'informazione importante per il client,
utilizzare un overload della procedura proposta ;)
-----------------------------------------------------------
procedure Upload(nomefile: string; ContentType: string = String.Empty);
var Resp : HttpResponse;
    TheFile : FileInfo;
    ContType : TObject;
    Header : string;
begin
  Resp:=HttpContext.Current.Response;
  TheFile:=FileInfo.Create(nomefile);
  // reperimento del content-type dal reggistro di sistema
  ContType := ContentType;  
  if ContType = String.Empty then
    try;
      ContType :=
        Registry.ClassesRoot.OpenSubKey(TheFile.Extension).GetValue(
          'Content Type',
          'application\octet-stream'
        );
    except;
      ContType := 'application\octet-stream';
    end;
 
  // il resto della procedura è uguale a quella proposta
  Resp.ContentType:=ContType.ToString;
  Header:=System.String.Format(
            'Attachment; filename={0}', 
            TheFile.Name
          );
  Resp.AppendHeader('Content-Disposition', Header);
  Resp.WriteFile(TheFile.FullName);
  Resp.&End;
end;
----------------------------------------------------------
chiedo venia per qualsiasi errore di sintassi e
ortografia del codice dovuto al fatto che non ho un
editor Delphi.NET sottomano e che di solito programmo
in C# per quanto riguarda .NET.
	Ciao
	MassimoB
 
---------------------------------
http://www.massimobeschi.it/
---------------------------------
Se tu pagare come dici tu ...
Io lavorare come dico io ...
Se tu pagare come dico io ...
Io lavorare come dici tu ...
---------------------------------

 in C# per quanto riguarda .NET.
Buuuuuuuuuuuuuu... :-D
Sto scherzando, ovviamente. ;-)


   se mi addormentassi sui tasti» (Daniele Luttazzi)
	Ciao
