WebAPI - zwrócenie CSV bez tworzenia pliku po stronie serwera

Odpowiedz Nowy wątek
2015-01-30 11:32
ne0
0

Hej,

mniej więcej mam funkcji w WebAPI który ma za zadanie zwrócić plik CSV:

 HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content = new StreamContent(new FileStream(filePath, FileMode.Open, FileAccess.Read));
              response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/csv");
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = "Visits.csv";

            return response;

Mam teraz takie pytanie czy jest możliwość stworzenia tego pliku jakoś w pamięci i z niej pobranie go do respone.Content? Bo obecnie na początku tej funkcji tworze ten plik na pulpicie i nie wiem czy to zadziała później :/

Pytanie motywuje tym że pliki które mi zwraca ten serwis są puste i wydaje mi sie ze nie ma dostępu do pulpitu u mnie na kompie.


Pomogłem? To dobrze :)

Pozostało 580 znaków

2015-01-30 12:01
0

Użyj MemoryStream zamiast FileStream.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
to jak ma caly kod wygladac? - ne0 2015-01-30 13:15
Zależy jak tworzysz ten plik. Pytaj w postach, a nie komentarzach. - somekind 2015-01-30 13:18

Pozostało 580 znaków

2015-01-30 13:19
ne0
0

Tak mam teraz:

        public HttpResponseMessage ExportVisits()
        {
            string pathDesktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string filePath = pathDesktop + "\\Visits.csv";

            if (!File.Exists(filePath))
            {
                File.Create(filePath).Close();
            }
            string delimter = ",";

            byte[] bytes = null;
            try
            {
                using(MemoryStream ms = new MemoryStream())
                using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    bytes = new byte[(file.Length)];
                    file.Read(bytes, 0, (int) file.Length);
                    ms.Write(bytes, 0, (int)file.Length);                  
                }
            }
            catch (Exception e)
            {
               //return false;
            }
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content =  new StreamContent(new MemoryStream(bytes));
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/csv");
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = "Visits.csv";
            return response;         
        }

I jak uzyje fiddlera to niespecjalnie to dziala, nic widze w nim tego pliku ani jakis danych, zgadza sie np. rozmiar wysylanych danych.


Pomogłem? To dobrze :)
edytowany 2x, ostatnio: ne0, 2015-01-30 13:20

Pozostało 580 znaków

2015-01-30 13:30
0

To nie jest kod o który pytałem. Skąd biorą się dane w pliku Visits.csv?
Po prostu zamiast pisać dane do pliku na dysku przez FileStream zapisz do MemoryStream, a potem zwróć ten MemoryStream w response.Content.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2015-01-30 13:35
ne0
0

z repozytorium dostaje liste obiektow, na jej podstawie używając filestream pisze do pliku, tworzać CSV, który potem chce zwrócić


Pomogłem? To dobrze :)

Pozostało 580 znaków

2015-01-30 13:39
0

No więc zapisz tę listę do MemoryStream zamiast pliku i tyle. :)


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2015-01-30 13:42
ne0
0

W ten sposób:

 try
            {
                using (MemoryStream writer = new MemoryStream())
                {
                    bytes = new byte[(file.Length)];
                    file.Read(bytes, 0, (int) file.Length);
                    writer.Write(bytes, 0, (int) file.Length);
                    foreach (var li in list)
                    {
                        var t = GetBytes(li.AverageTimeBetween + ", " + li.How );
                        writer.Write(t, 0, t.Length);
                    }
                    writer.Close();
                }
            }
            catch (Exception e)
            {
               //return false;
            }
            file.Close();

            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content =  new StreamContent(new MemoryStream(bytes));
              response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/csv");
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = "Visits.csv";

            return response;

?
też nie działa i nie wiem co to jest co zwraca mi takie zapytanie (patrze w fidler)

Takie coś mam jako zawartość tego pliku:

{"version":{"major":1   minor:1 build:-1    revision:-1 majorRevision:-1    minorRevision:-1}   content:{"headers":[{"key":"Content-Type"   value:["text/csv"]} {"key":"Content-Disposition"    value:["attachment; filename=Visits.csv"]}]}    statusCode:200  reasonPhrase:"OK"   headers:[]  requestMessage:null isSuccessStatusCode:true}

Ktoś coś? :(


Pomogłem? To dobrze :)
edytowany 3x, ostatnio: ne0, 2015-01-30 15:49

Pozostało 580 znaków

2015-01-30 16:16
0

Nie używaj żadnego file!!!
Użyj jednego MemoryStreama, do którego zapiszesz swoje dane (tak jak do każdego innego Streama w .NET), a potem go zwrócisz w HttpResponseMessage.

Przepraszam, nie umiem prościej tego wytłumaczyć.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
edytowany 2x, ostatnio: somekind, 2015-01-30 16:17

Pozostało 580 znaków

2015-01-30 16:33
ne0
0

No to jak mam zadeklarować tą tablicę bytes ? muszę mieć jej rozmiar jakoś :/
mam listę obiektów "list", w każdym obiekcie są jakieś dane. chce z tego zrobić CSV i to zwrócić...
EDIT:

            var list = repository.MakeACall();

            byte[] bytes = null;
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

                using (MemoryStream writer = new MemoryStream())
                {
                    foreach (var li in list)
                    {
                        var t = GetBytes(li.AverageTimeBetween + ", " + li.How);
                        writer.Write(t, 0, t.Length);
                    }             
                    response.Content = new ByteArrayContent(writer.ToArray());
                }           

            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/csv");
            response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            response.Content.Headers.ContentDisposition.FileName = "Visits.csv";
            var r = Request.CreateResponse(HttpStatusCode.OK, bytes);
            r.Content.Headers.ContentType = new MediaTypeHeaderValue("application/csv");
            return response;

co robię źle?
Wiem że dane są w tej liście, jest około 15 000 rekordów. Jak popatrze w fiddler to mi przychodzi Body o wielkości 310 przykładowo... :/


Pomogłem? To dobrze :)
edytowany 2x, ostatnio: ne0, 2015-01-30 16:44

Pozostało 580 znaków

2015-01-30 18:08
1

A, czyli nie umiesz korzystać ze strumieni. Generalnie strumienie są oparte o taki fajny wzorzec Dekorator, dzięki czemu możemy opakować strumień - medium transmisyjne (plik - FileStream, sieć - NetworkStream, pamięć - MemoryStream) w strumień pozwalający na wygodne czytanie i pisanie (np. StreamWriter, StreamReader).

Wielkiej filozofii w tym nie ma:

using (var ms = new MemoryStream())
{
    using (var sw = new StreamWriter(ms))
    {
        foreach (var visit in list)
        {
            string line = string.Join(",", visit.AverageTimeBetween, visit.How);
            sw.WriteLine(line);
            sw.Flush();
        }

        ms.Position = 0;

        response.Content =  new StreamContent(ms);
    }
}

"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."

Pozostało 580 znaków

2015-02-02 09:41
ne0
0

Dalej jest ten sam problem że w tym pliku nic nie ma praktycznie oprócz tego co wcześniej napisałem :/ tak jakby w ogóle nie dodawał tego do Content


Pomogłem? To dobrze :)

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0