2010-02-10 12 views
10

Chcę przesłać plik do przeglądarki ze strony internetowej przy użyciu usługi internetowej. Aktualnie czytam plik w tablicy bajtowej base64 i zwracam go z usługi sieciowej. Ta usługa sieciowa jest wywoływana ze strony internetowej i utknąłem na tym, jak przesłać ją jako oryginalny plik do przeglądarki. Idealnie chciałbym przeczytać tablicę bajtów w strumieniu pamięci, a następnie napisać ją do strumienia odpowiedzi, jeśli to możliwe, aby użytkownik końcowy po prostu pobrał plik.Pobierz plik z serwisu WWW - w witrynie ASP.NET

+0

i co czy problem dotyczy tego podejścia? Nie zadałeś pytania, więc prawdopodobnie szybko się zamknę. – Oded

Odpowiedz

12

Najpierw, zamiast wysyłać tablicę bajtów base64, niech usługa sieciowa po prostu zwróci tablicę bajtów dla pliku. Response.OutputStream.Write() automatycznie zakoduje 64 bajty, więc równie dobrze możesz je zakodować w swoim strumieniu pamięci.

Po drugie, potrzebujesz więcej niż bajtów. Będziesz potrzebować metadanych skojarzonych z plikiem. W poniższym fragmencie umieściłem wszystkie te metadane w osobnej klasie (lokalna instancja o nazwie "plik"). Następnie użyj tego fragmentu, gdy masz już potrzebne dane:

Response.Clear(); 
Response.ClearHeaders(); 
Response.ContentType = file.ContentType; 
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + file.FileName + "\""); 
Response.AddHeader("Content-Length", file.FileSize.ToString()); 
Response.OutputStream.Write(file.Bytes, 0, file.Bytes.Length); 
Response.Flush(); 
Response.End(); 
+3

Ostrożnie z Response.End() http://stackoverflow.com/questions/1087777/is-response-end-considered-harmful –

+0

@Todd Smith: Dzięki za wskaźnik. Byłem świadomy problemu, ale masz rację, że inni nie; może to być poważny błąd. Jednak w przypadku pobierania pliku nie ma potrzeby dalszego przetwarzania, które powinno zostać wykonane, a zatem 'Response.End()' * jest * prawdopodobnie poprawnym połączeniem. Z pewnością jest w moim przypadku. – Randolpho

+2

Czy powinienem użyć Response.Close() zamiast Repsonse.End(), a następnie? – user210757

3

To możliwe, trzeba upewnić się, że jawnie ustawić ContentType z httpResponse, na przykład:

Response.ContentType = "image/jpeg"; 
Response.OutputStream.Write(buffer, 0, buffer.Length); 

Jeśli chcesz kontrolować nazwę pliku, musisz dodać zawartość - nagłówek rozłożenia. Google może pomóc Ci znaleźć właściwy sposób na uporządkowanie tego.

+0

+1, mimo że pominięto opcję Content-Disposition, która jest najważniejsza dla pobierania plików. Edycja: A potem ją dodałeś. Więc zignoruj ​​to. :) – Randolpho

0

To naprawdę zależy od interfejsu do twojego serwisu. Tj. SOAP, REST, ASPX.

Jedna rzecz, którą możesz spróbować, to zmienić typ zawartości w odpowiedzi na "Aplikacja/strumień-oktetu". Lub coś podobnego, aby przekazać odbiorcy typ MIME.

Jeśli korzystasz z funkcji WCF, możesz korzystać z funkcji Stream jako metody zwracania w usłudze internetowej.

1

Zazwyczaj złym pomysłem jest osadzenie pliku w serwisie WWW. Po prostu dodajesz obciążenie i złożoność bez żadnych rzeczywistych korzyści.

Zamiast tego należy podać IHttpHandler, aby obsłużyć przesłanie pliku. Większość serwerów internetowych udostępnia również interfejsy API pomocników, aby uprościć to, np. w ASP.NET można uzyskać dostępu do pliku przesłanego z:

HttpContext.Request.Files [0]

Istnieje wiele skryptów JavaScript wysyłania plików, które uprości to na kliencie: http://www.phpletter.com/Demo/AjaxFileUpload-Demo/

+0

Próbuję pobierać pliki do klienta, a nie przesyłać na serwer – user210757

+0

, który to link jest spamem lub stracił swój kontekst w czasie. – mcy

Powiązane problemy