/ Forside / Teknologi / Udvikling / ASP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
ASP
#NavnPoint
smorch 9259
Harlekin 1866
molokyle 1040
Steffanst.. 758
gandalf 657
smilly 564
gibson 560
cumano 530
MouseKeep.. 480
10  Random 410
Download manager
Fra : Kim Bach Petersen


Dato : 18-05-02 22:47

Hvordan laver man egentlig en download manager, fx som på
activedeveloper.dk, hvor filens virtuelle adresse ikke afsløres for
brugeren? (helst .net, ellers bare 'classic'...)

Kim



 
 
Jakob Andersen (19-05-2002)
Kommentar
Fra : Jakob Andersen


Dato : 19-05-02 01:35

"Kim Bach Petersen" <kim@kensho.dk> wrote in message
news:ac6i4a$7fo$2@sunsite.dk...
> Hvordan laver man egentlig en download manager, fx som på
> activedeveloper.dk, hvor filens virtuelle adresse ikke afsløres for
> brugeren? (helst .net, ellers bare 'classic'...)

Man streamer indholdet af filen til clienten.

I klassisk ASP brugte man ADO's Stream objekt.(Søg tilbage i gruppen, det
har været diskuteret utallige gange)

I .NET bliver det straks sjovere, det kan faktisk gøres så let som
nedenunder:

<%@ Page Language="c#" %>
<%@ Import Namespace="System.IO" %>

<script language="c#" runat="server">
private void Page_Load( object Sender, EventArgs e){
//Vi åbner et stream object der peger på filen
Stream objStream = File.OpenRead(@"C:\Inetpub\wwwroot\findosrub.gif");

//Vi sætter størrelsen på vores buffer
//samt definerer vores tæller værdi
int intBuffer = 255;
int intLaest = 0;

//Vi definerer et bytearray da BinaryWrite
// funktionen kræver dette dataformat
byte[] arrByte = new byte[intBuffer];

//Vi fjerner alt indhold fra bufferen
//og sætter en ny mime type
Response.ClearContent();
Response.ContentType = "image/gif";

//Vi løber filen igenne så længe Read metoden returner mere en 0 bytes
while(0 != (intLaest = objStream.Read(arrByte, 0 , intBuffer-1))){
//Vi lægger vores data over i intTotal
intTotal += intLaest;

//Hvis vores Buffer er fyldt op udskriver vi byte arrayet
if (intLaest == intBuffer){
Response.BinaryWrite(arrByte);
//Hvis bufferen ikke er fyldt opretter vi en kopi med
//vores nye indhold og udskriver
}else{
byte[] arrCopy = new byte[intLaest];
Array.Copy(arrByte, 0, arrCopy, 0, intLaest);
Response.BinaryWrite(arrCopy);
}
}
Response.End();
}
</script>

--
Jakob Andersen



Kim Bach Petersen (19-05-2002)
Kommentar
Fra : Kim Bach Petersen


Dato : 19-05-02 13:40

> Man streamer indholdet af filen til clienten.

Det er rigtig godt; specielt, at man kan adressere filer udenfor webstedet!

Men jeg har problemer med at få browseren til at reagere rigtigt på den
streamede fil. Det vil for det meste være .doc- og .pdf-filer, der skal
dowloades, altså formater browseren understøtter. Jeg regner med at det er
her skoen trykker:

>Response.ContentType = "image/gif";

Sætter jeg den til "binary/octet-stream" eller "text/html" læser browseren
det som en simpel tekstfil og det er jo ikke videre læsbart... Findes der
værdier for .doc og .pdf? Eller andre måder at tilkendegive, at der kommer
indhold af en særlig type?

Kim


BTW, et nærmere kik på activedeveloper.dk afslørede, at de faktisk ikke
bruger noget serverside men blot en simpel refresh à lá:

<META HTTP-EQUIV="Refresh" CONTENT="1;URL=dokument.doc">

Den metode kan få browseren til at åbne dokumentet rigtigt (ligesom et
simpelt link), men tilbyder til gengæld ingen sikkerhed, fordi dokumentet så
skal ligge i en virtuel mappe...




Jakob Andersen (19-05-2002)
Kommentar
Fra : Jakob Andersen


Dato : 19-05-02 14:05

"Kim Bach Petersen" <kim@kensho.dk> skrev i en meddelelse
news:ac86f7$24f$1@sunsite.dk...
> Men jeg har problemer med at få browseren til at reagere rigtigt på den
> streamede fil. Det vil for det meste være .doc- og .pdf-filer, der skal
> dowloades, altså formater browseren understøtter. Jeg regner med at det er
> her skoen trykker:

application/pdf
application/msword

Se komplet liste på:
<ftp://ftp.isi.edu/in-notes/iana/assignments/media-types/media-types>

> Sætter jeg den til "binary/octet-stream" eller "text/html" læser browseren
> det som en simpel tekstfil og det er jo ikke videre læsbart... Findes der
> værdier for .doc og .pdf? Eller andre måder at tilkendegive, at der kommer
> indhold af en særlig type?

Jeg plejer at lave en databasetabel med filextensions og mimetyper, så når
filen skal åbnes tager jeg extension og henter mime typen fra databasen.

Dit næste problem bliver nok at når folk henter filen kommer den til at
hedde navnet på din aspx side og ikke navnet på dokumentet, til dette skal
du bruge denne header:

Response.AddHeader("Content-Disposition", "attachment; filename="fil.pdf")

Og måske vil du også få det problem at IE blot vil prøve at åbne PDF'er/Word
dokumenter i browseren og ikke spørge om den skal hente den, det løses ved
at sætte følgende mime-type:

Response.ContentType = "application/octet-stream"

--
Jakob Andersen




Kim Bach Petersen (19-05-2002)
Kommentar
Fra : Kim Bach Petersen


Dato : 19-05-02 20:02

Tak, som altid havde du noget, der kunne bringe mig videre!

> Og måske vil du også få det problem at IE blot vil prøve at åbne
PDF'er/Word
> dokumenter i browseren og ikke spørge om den skal hente den, det løses ved
> at sætte følgende mime-type:
>
> Response.ContentType = "application/octet-stream"

Faktisk ser det ikke ud til at gøre nogen forskel på min maskine (IE6) om
jeg vælger 'octet-strem', 'ms-word' eller 'pdf' - uanset hvad, kommer
dialogen filoverførsel og jeg kan vælge at åbne eller gemme. Faktisk ville
jeg synes at det var ret cool om folk kunne vælge at browseren automatisk
åbnede dokumentet, men det er nu også fint som det er - det væsentlige i
første omgang er at kunne styre adgangen til dokumenterne.

Mystisk nok kommer dialogen 'Filoverførsel' to gange efter hinanden hvis man
vælger 'Åbn' - det undrer jeg mig lidt over, men det er til at leve med...

Tak igen, Kim





Jakob Andersen (19-05-2002)
Kommentar
Fra : Jakob Andersen


Dato : 19-05-02 20:17

"Kim Bach Petersen" <kim@kensho.dk> skrev i en meddelelse
news:ac8sr7$ki$1@sunsite.dk...
> Tak, som altid havde du noget, der kunne bringe mig videre!

Det var da så lidt


> Mystisk nok kommer dialogen 'Filoverførsel' to gange efter hinanden hvis
man
> vælger 'Åbn' - det undrer jeg mig lidt over, men det er til at leve
med...

Dette skyldes lige en smutter fra min side, prøv med at udskifte
Content-Dispostion header med denne:

Response.AddHeader("Content-Disposition", "filename="fil.pdf")

--
Jakob Andersen



Kim Bach Petersen (19-05-2002)
Kommentar
Fra : Kim Bach Petersen


Dato : 19-05-02 21:09

> Response.AddHeader("Content-Disposition", "filename="fil.pdf")

Perfekt!

Kim



Jakob Andersen (20-05-2002)
Kommentar
Fra : Jakob Andersen


Dato : 20-05-02 02:29

"Kim Bach Petersen" <kim@kensho.dk> wrote in message
news:ac90pa$aa0$1@sunsite.dk...
> Perfekt!

Ikke helt


Jeg kom lige i tanke om at man kan streame direkte fra en filestream til en
buffer og så ud istedet:


<%@ Import Namespace="System.IO" %>
<script runat="server" language="c#">
void Page_Load(){
FileStream objFileStream= new FileStream(@"c:\dokumenter\foo.doc",
FileMode.Open);
int FilStorrelse = (int)objFileStream.Length;

byte[] Buffer = new byte[FilStorrelse];
objFileStream.Read(Buffer, 0, FilStorrelse);
objFileStream.Close();
Response.ContentType = "application/octet-stream";
Response.AddHeader( "content-disposition","filename=foo.doc");
Response.BinaryWrite(Buffer);
}
</script>

Og hvis man virkelig vil have et kraftigt værktøj til sin "download manager"
som du kalder det, så laver du en webhandler som denne:

<%@ WebHandler Language="C#" Class="GetFile" %>

using System.Web;
using System.IO;

public class GetFile : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
string strSti= @"C:\Inetpub\wwwroot\" + context.Request["fil"];

FileStream objFileStream= new FileStream(strSti, FileMode.Open);
int FilStorrelse = (int)objFileStream.Length;

byte[] Buffer = new byte[FilStorrelse];
objFileStream.Read(Buffer, 0, FilStorrelse);
objFileStream.Close();
context.Response.ContentType = "image/gif";
context.Response.AddHeader( "content-disposition","filename=foo.doc");
context.Response.BinaryWrite(Buffer);
}
public bool IsReusable
{
get { return true; }
}
}


--
Jakob Andersen



Kim Bach Petersen (20-05-2002)
Kommentar
Fra : Kim Bach Petersen


Dato : 20-05-02 11:24

> Og hvis man virkelig vil have et kraftigt værktøj til sin
> "download manager" som du kalder det, så laver du en
> webhandler som denne:

Hey, vildt, men vel også oplagt ikke at bruge Page-objektet, når der ikke
skal genereres en side - man får da nogle muligheder med
..net-objektmodellen. Anyway, nu fik jeg så lært lidt om HTTP handlers,
desværre får jeg nok først prøvet det af om nogle dage...

Kim



Jesper Stocholm (31-05-2002)
Kommentar
Fra : Jesper Stocholm


Dato : 31-05-02 12:49

Jakob Andersen wrote in news:ac9jj8$iri$1@news.cybercity.dk:

> Og hvis man virkelig vil have et kraftigt værktøj til sin "download
> manager" som du kalder det, så laver du en webhandler som denne:
>
> <%@ WebHandler Language="C#" Class="GetFile" %>
> using System.Web;
> using System.IO;
> public class GetFile : IHttpHandler
> {
> public void ProcessRequest (HttpContext context)
> {
> string strSti= @"C:\Inetpub\wwwroot\" +
> context.Request["fil"];
> FileStream objFileStream= new FileStream(strSti, FileMode.Open);
> int FilStorrelse = (int)objFileStream.Length;
>
> byte[] Buffer = new byte[FilStorrelse];
> objFileStream.Read(Buffer, 0, FilStorrelse);
> objFileStream.Close();
> context.Response.ContentType = "image/gif";
> context.Response.AddHeader(
> "content-disposition","filename=foo.doc");
> context.Response.BinaryWrite(Buffer);
> }
> public bool IsReusable
> {
> get { return true; }
> }
> }

nu har jeg prøvet at få dette script til at virke som en
download-manager ... men jeg kan ikke helt få det til at
virke.

jeg prøvede først blot at kopiere koden ind i en .aspx-fil
(med et par ændringer), men den giver mig en lidt uforståelig
fejl ... nemlig:

"The directive 'WebHandler' is unknown." [1]

Hvis jeg så prøver at kigge lidt omkring efter WebHandler, så ser
det ud til, at den blver brugt i en webservice ... men kan det passe,
at jeg er "nødt" til at lave dette ?

Min kode er :

**** File getFile.aspx ****

<%@ WebHandler Language="C#" Class="GetFile" %>
<script language="C#" runat="server">
using System.Web;
using System.IO;

public class GetFile : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{   
   string strFile = context.Request["file"];
   string strSti= @"Z:\inetpub\data\" + strFile

   FileStream objFileStream= new FileStream(strSti, FileMode.Open);
   int FilStorrelse = (int)objFileStream.Length;

   byte[] Buffer = new byte[FilStorrelse];
   objFileStream.Read(Buffer, 0, FilStorrelse);
   objFileStream.Close();
   context.Response.ContentType = "image/gif";
   context.Response.AddHeader( "content-disposition","filename="+strFile);
   context.Response.BinaryWrite(Buffer);
}
public bool IsReusable
{
get { return true; }
}
}
</script>

Er det mig, der totalt misforstår anvendelsen af scriptet ?

:)


[1] Fejlen kan ses på http://stocholm.dk/getFile.aspx?file=txtConverter.exe

--
Jesper Stocholm
http://stocholm.dk
http://asp.stocholm.dk
Svar til gruppen og ikke til mig privat pr. email :|

Kim Bach Petersen (31-05-2002)
Kommentar
Fra : Kim Bach Petersen


Dato : 31-05-02 19:09

> nu har jeg prøvet at få dette script til at virke som en
> download-manager ... men jeg kan ikke helt få det til at
> virke.

Scriptet skal ikke køres som almindelig .aspx-side, men er beregnet til at
overtage asp's almindelige server-response på en request af en fil. Som du
kan se implementerer klassen IHttpHandler, som tager sig af http-requests.
Dermed behøver siden ikke at kalde 'page'-objektet - som jo er overflødigt,
når der ikke skal genereres en HTML-side - fortolkningen flyttes dermed et
trin bagud i kompileret kode med de fordele det nu har.

En af fiduserne ved dette er, at de downloadede filer ikke behøver at gå
omkring browseren. Når en fil til download kaldes ved serveren, at den skal
sendes på en særlig måde og dermed kommer dialogen 'fil-overførsel' uden den
kaldende side forstyrres. HttpHandleren kan sættes til at reagere på enkelte
filer, fil-typer og mapper.

Men ellers: Scriptet skal kompileres og lægges i '\bin' og derudover
registreres i 'web.config'.

Du kan læse mere præcist hvordan i QuickStart under:

ASP.NET Web Applications
HTTP Handlers and Factories

Ret cool feature!

Kim



Søg
Reklame
Statistik
Spørgsmål : 177559
Tips : 31968
Nyheder : 719565
Indlæg : 6408938
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste