Q:

Using A Local file path in a Streamwriter object ASP.Net

I am trying to create a csv file of some data. I have wrote a function that successfully does this....
Private Sub CreateCSVFile(ByVal dt As DataTable, ByVal strFilePath As String)
        Dim sw As New StreamWriter(strFilePath, False)
        ''# First we will write the headers. 
        ''#DataTable dt = m_dsProducts.Tables[0]; 
        Dim iColCount As Integer = dt.Columns.Count
        For i As Integer = 0 To iColCount - 1
            sw.Write(dt.Columns(i))
            If i < iColCount - 1 Then
                sw.Write(",")
            End If
        Next
        sw.Write(sw.NewLine)
        ''# Now write all the rows. 
        For Each dr As DataRow In dt.Rows
            For i As Integer = 0 To iColCount - 1
                If Not Convert.IsDBNull(dr(i)) Then
                    sw.Write(dr(i).ToString())
                End If
                If i < iColCount - 1 Then
                    sw.Write(",")
                End If
            Next
            sw.Write(sw.NewLine)
        Next
        sw.Close()

    End Sub

The problem is I am not using the streamwriter object correctly for what I trying to accomplish. Since this is an asp.net I need the user to pick a local filepath to put the file on. If I pass any path to this function its gonna try to write it to the directory specified on the server where the code is. I would like this to popup and let the user select a place on their local machine to put the file....
 Dim exData As Byte() = File.ReadAllBytes(Server.MapPath(eio))
        File.Delete(Server.MapPath(eio))
        Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fn))
        Response.ContentType = "application/x-msexcel"
        Response.BinaryWrite(exData)
        Response.Flush()
        Response.End()

I am calling the first function in code like this...
 Dim emplTable As DataTable = SiteAccess.DownloadEmployee_H()
  CreateCSVFile(emplTable, "C:\\EmplTable.csv")

Where I dont want to have specify the file loaction (because this will put the file on the server and not on a client machine) but rather let the user select the location on their client machine. 
Can someone help me put this together? Thanks in advance.
I have recreated my export function and now it lets the usr select a download path, but one column in the data being downloaded has data in the form of "Doe, John" this column is called "EPLNME" this messes up the output file because its reading the comma in the data and now the data is off by a column in the output file can someone help me stop this specific incident im not sure how I can. Here is the code...
Private Sub ExportCSV(ByVal data As DataTable, ByVal nameOfFile As String)
    Dim context As HttpContext = HttpContext.Current
    context.Response.Clear()
    context.Response.ContentType = "text/csv"
    context.Response.AddHeader("Content-Disposition", "attachment; filename=" + nameOfFile + ".csv")

    ''#Write column header names
    For i = 0 To data.Columns.Count - 1
        If (i > 0) Then
            context.Response.Write(",")
        End If
        context.Response.Write(data.Columns(i).ColumnName)
    Next
    context.Response.Write(Environment.NewLine)

    ''#Write data
    For Each row As DataRow In data.Rows
        For i = 0 To data.Columns.Count - 1
            If (i > 0) Then
                context.Response.Write(",")
            End If
            context.Response.Write(row.Item(i).ToString())
        Next
        context.Response.Write(Environment.NewLine)
    Next
    context.Response.End()

End Sub

A:

First, you need to overload your function like this, to allow sending your output directly to either a stream or a path:
Private Sub CreateCSVFile(ByVal dt As DataTable, ByVal strFilePath As String)
    Using sw As New StreamWriter(strFilePath)
        CreateCSVFile(dt, sw)
    End Using
End Sub

Private Sub CreateCSVFile(ByVal dt As DataTable, ByVal outStream As TextWriter)
    ''# First we will write the headers.  
    Dim delimiter As String = String.Empty
    For Each col As DataColumn in dt.Columns
         outStream.Write(delimiter)
         outStream.Write(col.ColumnName)
         delimiter = ","
    Next col        
    outStream.Write(outStream.NewLine)

   int flushCount = 0;

    ''# Now write all the rows. 
    For Each dr As DataRow In dt.Rows
        delimiter = String.Empty
        For i As Integer = 0 To dt.Columns.Count -1
            outStream.Write(delimiter)

            If Not Convert.IsDBNull(dr(i)) Then
                outStream.Write("""") ''#Wrap fields in quotes to allow for commas in field data

                ''# Need to escape the quotes as well
                outStream.Write(dr(i).ToString().Replace("""", """"""))

                outStream.Write("""") 
            End If
            delimiter = ","
        Next i
        outStream.Write(outStream.NewLine)

        ''# Flush the buffer periodically
        flushCount += 1
        If flushCount > 100 Then
             outStream.Flush()
             flushCount = 0
        End If
    Next dr
End Sub

Notice that your function works pretty much exactly the same as before, but you can now write to a file or directly to a stream, and you didn't have to re-write a lot of code to make it work.  Pretty much anything you write that works with files should be written this way.  I made a few other improvements to the code as well, but the main thing is the method that does the actual work should always accept a TextWriter and then just add overloads if you want to be able to accept anything else like a file path.
Now what you can do is take the Content Type and Header from Ben Robinson's answer and use this new method to write directly to the asp.net response buffer:
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=NameOfFile");
CreateCSVFile(SiteAccess.DownloadEmployee_H(), Response.Output)
Response.Flush()
Response.End()

