Отправка созданного CSV на лету обратно клиенту для скачивания - PullRequest
2 голосов
/ 11 марта 2011

Я конвертирую кучу приложений FOXPRO / FOXWEB в ASP.NET.

Базовая БД по-прежнему остается foxpro (на данный момент).

Я передаю таблицу в некоторый код VB.NET, который я хочу преобразовать в файл CSV и отправить обратно клиенту для загрузки. И это работает! Вроде ... Это работает иногда, но в других случаях, вместо того, чтобы спрашивать меня, хочу ли я загрузить файл CSV, он просто выбрасывает файл в окно браузера.

Со стороны asp я передаю объект ответа, таблицу и имя файла csv.

<%
   Dim xls_fn As String = "test01.csv"

   'OLEDB call to fill up 'tbl' ... this works.

   sendTableAsCSVtoClient(response, tbl, xls_fn)
%>

В файле clsCommon.vb у меня есть следующий код:

Option Explicit On 
'Option Strict On

Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.Page
Imports System.IO
Imports Microsoft.VisualBasic
Imports System.Diagnostics
Imports System.Data
Imports System.Data.OleDb


Public Class clsCommon
    Inherits Page

    Public Shared Function enq(ByVal str As String) As String
        Dim dq As String
        dq = """"
        Return dq & str & dq
    End Function

    ' some other functions and subs defined in here ... blah blah blah
    ' ...

    Public Shared Function sendTableAsCSVtoClient(ByVal resp As HttpResponse, ByVal sqlTable As DataTable, ByVal xls_fn As String) As Boolean
        Dim r As DataRow
        Dim c As DataColumn
        Dim sep As String = ","
        Dim FileExtension As String
        Dim lcFileNameONLY As String
        Dim i As Integer
        Dim dq As String = """"

        FileExtension = UCase(Path.GetExtension(xls_fn))
        lcFileNameONLY = UCase(Path.GetFileNameWithoutExtension(xls_fn))

        resp.Clear()
        resp.ClearContent()
        resp.ClearHeaders()
        resp.ContentType = "application/vnd.ms-excel"
        resp.AddHeader("Content-Disposition", "inline; filename=" & lcFileNameONLY & ".csv")
        For Each c In sqlTable.Columns
            resp.Write(UCase(c.ColumnName) & sep)
        Next
        resp.Write(vbCrLf)

        For Each r In sqlTable.Rows
            For i = 0 To sqlTable.Columns.Count - 1
                resp.Write(enq(r(i)) & sep)
            Next
            resp.Write(vbCrLf)
        Next

        resp.End()
        Return True

    End Function

End Class
  1. Что вызывает это?
  2. Как мне обойти это?

Полагаю, не имеет значения, что источником данных является таблица. Обратите внимание, что файл создается на лету и никогда не существует в файловой системе сервера.

ТХ, ПТФ

Ответы [ 3 ]

2 голосов
/ 11 марта 2011

Вместо использования Content-Disposition заголовка Inline, используйте Attachment - это всегда будет запрашивать загрузку.

Измените следующую строку с:

resp.AddHeader("Content-Disposition", "inline; filename=" & lcFileNameONLY & ".csv")

К

resp.AddHeader("Content-Disposition", "attachment; filename=" & lcFileNameONLY & ".csv")

См. это и это для примеров.

Встроенный тип означает, что браузер может сделать его встроенным (в браузере), если знает, как это сделать.

И посмотрите этот ТАК вопрос, спрашивающий, почему inline иногда запрашивает загрузку (полная противоположность вашего вопроса ...).

1 голос
/ 11 марта 2011

Я согласен с Oded и chmullig, что вы должны изменить Content-Disposition, но я также рекомендую использовать буфер и завершить ответ сбросом:

 resp.Clear()
 resp.Buffer = true

 'build csv

 resp.Flush()
 resp.Close()

Я полагаю, что вызов .End () вызывает исключение ThreadAbortException, чтобы остановить выполнение, что может вызвать проблемы в зависимости от того, как вы обрабатываете ваши исключения. Подробнее см. Здесь

1 голос
/ 11 марта 2011

Проблема в вашем Content-disposition заголовке.Это должно быть "attachment" вместо "inline".

Возможно, вы также захотите установить тип контента равным "text/csv" вместо "application/vnd.ms-excel".Таким образом, вы более точны, и если они предпочитают использовать что-то еще для CSV, это должно работать лучше.Однако, для внутреннего приложения, возможно, vnd.ms-excel будет работать лучше?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...