determine content-length of html string - asp.net

I am exporting a HTML table to excel by sending the data as a HTML Table string and setting the content headers:
Dim html as String = "<table><tr><td>example<td></tr></table>"
context.Response.Clear()
context.Response.AddHeader("Content-Disposition", "attachment; filename=" & "exceldata-" & Now.ToString("yyyyMMddHHmmss") & ".xls")
'context.Response.AddHeader("Content-Length", ????)
context.Response.ContentType = "application/octet-stream"
context.Response.Write(response)
context.Response.End()
Is there a simple way of setting the content-length based on the size of the html string? Or should I just leave it blank anyway...would be nice to have the content-length ideally...
I am returning this using a GenericHandler in asp.net

Replace with the encoding of your choice, probably UTF8. Sorry for the C#:
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] bytes = encoding.GetBytes(html);
int length = bytes.Length;
Source: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.contentlength.aspx

This seems too easy, but is it not just equal to html.Length?

I haven't used ASP.NET, but I guess that the Length() method returns the length of the string in chars, not bytes, so it won't work if your server uses UTF-8 or Unicode for serving the pages.
As noted in another answer, just let the server fill it for you. If you think about it, you don't have to add it when you generate HTML pages from ASP since the web server would generate it based in the response from the ASP module.

Related

How to Decode the Encoded value?

Now am looking after my Friend's Project. In that project my friend encoded some value and store it in Database. Now I need to Use those values. So, I have to decode them. I Don't know where to start it...can anyone help me.
Given the Encoding method :
string strmsg = string.Empty;
byte[] encode = new byte[Text.Length];
encode = Encoding.UTF8.GetBytes(Text);
strmsg = Convert.ToBase64String(encode);
Text is the string which is encoded here.
Note : I Need to decode the "strmsg" value.
This should decode your strmsg back to your text.
byte[] decode = Convert.FromBase64String(strmsg); //strmsg is the encoded text
strmsg = Encoding.UTF8.GetString(decode); //this strmsg is your decoded original text

File fetch from database using asp

I am storing some the binary data for some files in a database (yes, I know this can be a bad idea). I am able to get the files out, with the correct content type, since I have stored it. But I'm having trouble getting the file to the client with the right filename. Right now I have the following code in a file called get_file.asp:
sSQL = "SELECT filename, contenttype, binarydata FROM new_attachment WHERE filename = '" & filename & "'"
oRs.Open sSQL, conn, 3, 3
If Not oRs.EOF Then
Response.ContentType = oRs(1)
Response.BinaryWrite oRs(2)
End if
This will return files correctly, but with the filename of 'get_file.asp', instead of, say, 'myfile.txt'. The url visited is .../get_file.asp?filename=myfile.txt.
Is there a way I could change the name of the file when the browsers prompts the user to save it somewhere?
You need to send out the correct header:
Response.ContentType = "text/html"
Response.AddHeader "Content-Disposition", "attachment; filename=YOURFILE.TXT"
You need to add a Content-Disposition header.
The header should look like this:
Content-Disposition: attachment; filename=<name of file>
Side note: The way you are concatenating SQL is open to SQL Injection - you should be using parameters.

ASP.NET: BOM in Server.Execute()

I'm using this to write to the Response stream:
using (var writer = new StringWriter())
{
context.Server.Execute(virtualpath, writer);
string s = writer.ToString().Replace(...);
context.Response.Write(s);
}
But I'm getting a byte order mark in the response. Am I screwing up the encoding? How do I NOT return the BOM?
EDIT: SOrry Rubens, my first example was incorrect.
Try this:
context.Server.Execute(virtualpath, context.Response.Output);
EDIT: So, try this to force your encoding:
MemoryStream ms = new MemoryStream();
StreamWriter writer = new StreamWriter(ms);
context.Server.Execute(virtualpath, writer);
context.Response.Write(Encoding.UTF8.GetString(ms.ToArray()).Replace(...));
Server.Execute() returns an encoded stream, but StringWriter() is intended to store simple .NET strings (which are 16-bit Unicode and don't have a BOM) and doesn't know how to decode the incoming bytes. So, the BOM in the response becomes literal characters in your string.
Try writing to a MemoryStream() instead, then decode that back into a string using whichever encoding (UTF-8 or whatever) that the Server.Execute() is passing back. Then you can parse it and write it back to your Response.

ASP.NET stream content from memory and not from file

The users have requested the option to "download" a csv file representation of GridView contents. Does anyone know how to do this without saving the file to the server but rather just streaming it to the user from memory?
Thanks
Implement an IHttpHandler.
I used something similar to the following in the ProcessResponse for outputing a CSV that had previously been constructed in a database table...
public void ProcessRequest(HttpContext context)
{
HttpResponse response = context.Response;
HttpRequest request = context.Request;
//Get data to output here...
//Turn off Caching and enforce a content type that will prompt to download/save.
response.AddHeader("Connection", "close");
response.AddHeader("Cache-Control", "private");
response.ContentType = "application/octect-stream";
//Give the browser a hint at the name of the file.
response.AddHeader("content-disposition", string.Format("attachment; filename={0}", _filename));
//Output the CSV here...
foreach(BatchDTO.BatchRecordsRow row in dtoBatch.BatchRecords)
response.Output.WriteLine(row.Data);
response.Flush();
response.Close();
}
There are a number of libraries that make generating a CSV easier, you should just be able to pass it the Response.OutputStream to have it write to there rather than to a file stream.
Use context.Response.OutputStream.
Here's an example.
I created a StringBuilder and dump the contents to the Response object using the following code ("csv" is the StringBuilder variable).
Response.ContentType = #"application/x-msdownload";
Response.AppendHeader("content-disposition", "attachment; filename=" + FILE_NAME);
Response.Write(csv.ToString());
Response.Flush();
Response.End();
I have used the RKLib export library a few times to great effect, this uses a memory stream and can be given any datatable which it will export as a csv download:
http://www.codeproject.com/KB/aspnet/ExportClassLibrary.aspx

ASP.NET Filename encoding while sending file

I am sending a file from ASP.NET Page to the browser. To properly send a filename I am adding a header:
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=" + filename);
The problem is that when file contains white spaces (e.g. "abc def") browser receives only "abc" part of the filename. I have tried with: Server.HtmlEncode but it didn't help.
Do you have any idea how to solve this problem?
PK
Put the file name in quotes:-
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
Don't UrlEncode. This is not the right way to escape a value for use in an HTTP structured header parameter. It only works in IE due to that browser's buggy handling, and even then not reliably.
For a space you can use a quoted-string as suggested by Anthony (+1). But the dirty truth of Content-Disposition is that there is no reliable, supported escaping scheme that can be used to put arbitrary characters such as ;, " or Unicode characters in the filename parameter. The only approach that works reliably cross-browser is to drop the filename parameter completely and put the desired filename in the URI as a trailing, UTF-8+URL-encoded path part.
See this answer for some background.
Filename with special symbols(e.g: space; # # ! $ ) or Non-Unicode characters either cannot be supported by some browsers or cause incorrect filename in client machine.
Here is an article by a Chinese called chanext, he gave a perfect way to solve this problem:
this article gave a sample code(written with c#) to show how to get perfect solution to this problem in the all four popular browsers (IE; Opera; Firefox and Chrome)
the filename "Microsoft.Asp.Net.doc" and "F ile;;!#%#^&y.doc" can both be output correctly using the way the author provided in this article.
http://ciznx.com/post/aspnetstreamdownloaddisplaynonunicodespacechar.aspx
Based on the code referenced by #chanext I cleaned it up and put it into a single extension method. Hope this can help someone.
Partial Class Uploader
Inherits Page
Private Sub UploadFile()
Dim sFileName As String
Dim oPdf As MigraDoc.Rendering.PdfDocumentRenderer
sFileName = "File Name With Spaces #22.pdf"
With Me.Request.Browser
If .Browser = "InternetExplorer" OrElse .Browser = "IE" Then
sFileName = sFileName.EncodeForIE
Else
sFileName = String.Format("""{0}""", sFileName)
End If
End With
oPdf = New MigraDoc.Rendering.PdfDocumentRenderer
oPdf.Document = FileFactory.CreatePdf()
oPdf.RenderDocument()
Using oStream As New MemoryStream
oPdf.Save(oStream, False)
Me.Response.Clear()
Me.Response.ContentType = "application/pdf"
Me.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", sFileName))
Me.Response.AddHeader("content-length", oStream.Length)
Me.Response.BinaryWrite(oStream.ToArray)
End Using
Me.Response.Flush()
Me.Response.End()
End Sub
End Class
Public Module StringExtensions
<Extension()>
Public Function EncodeForIE(Url As String) As String
Dim _
sReservedChars,
sEncodedString As String
sReservedChars = "$-_.+!*'(),#=&"
With New StringBuilder
Url.ToList.ForEach(Sub(C)
If Char.IsLetterOrDigit(C) OrElse sReservedChars.Contains(C) Then
.Append(C)
Else
With New StringBuilder
C.ToBytes.ToList.ForEach(Sub(B)
.AppendFormat("%{0}", Convert.ToString(B, 16))
End Sub)
sEncodedString = .ToString
End With
.Append(sEncodedString)
End If
End Sub)
Return .ToString
End With
End Function
<Extension()>
Public Function ToBytes(Chr As Char) As Byte()
Return Encoding.UTF8.GetBytes(Chr.ToString)
End Function
End Module

Resources