Mail Attachment in ASP.net - asp.net

Am trying to add an attachment to mail in asp.net VB.
I could send mail fine until I added the attachment code,
Dim attch As Attachment = New Attachment("http://sitehere.com/Documents/file.jpg")
mail.Attachments.Add(attch)
I am getting the error URI formats are not supported.
Any ideas why that is and what I can do about it?

The Attachment class expects either a path to a file on the file system, or a Stream.
Try:
Dim data As Byte() = New WebClient().DownloadData("http://sitehere.com/Documents/file.jpg")
Dim attachment As New Attachment(New MemoryStream(data), "file.jpg")
That's me doing my best to translate from C# to VB.NET so the syntax might not be 100% correct, but that's the general idea. That will download the data into a byte array, then create a memory stream from those bytes and pass that to the Attachment constructor.

You can't add an attachment straight from a URL. You'll need to download the file first, then add it as an attachment.
you can use HttpWebRequest to get the file as a stream, then attach the stream. That saves having to store the file on disk.

If you have the file locally in your server and in a folder which you know the path, dont use the uri for that,
Dim eMessage As New MailMessage
Dim attachLabel As Attachment
Dim location As String
loction= Server.MapPath("Documents\\file.jpg")
attachLabel = New Attachment(loction)
eMessage .Attachments.Add(attachLabel);
If you really want to send a file from another url, you may use HttpWebRequest to download that first and send it as Colin and Davy8 metnioned.

Related

Asp.Net 6.0 Redirect user to a URL containing json content and start download

I have a scenario where the user passes a fileName to download.
We don't download the file on the server and stream back to the user because of bandwidth restrictions
We get the file path to download, and redirect to the location where the json file would be hosted
[Route("[controller]/DownloadJsonFile")]
public async Task DownloadJsonFile(string fileName)
{
//Get the file name
string fileToDownload = "https://hostedfilelocation/....test.json"
Response.Redirect(fileToDownload);
}
Currently, this method ends up rendering the Json content on the browser.
Is there a way so that the browser can start automatically downloading the file?
That way it wouldn't take super long to render the file on the browser.
P.S. If the file is of type zip or gzip, it is not rendered on the browser but rather is automatically downloaded.
The application is a .Net 6 Asp.Net MVC application
I have tried the below code but the behavior is the same but it renders json on the browser instead of downloading it.
string fileToDownload = "https://hostedfilelocation/....test.json"
HttpResponse response = HttpContext.Response;
response.Clear();
response.ContentType = "application/octet-stream";
response.Headers.Add("Content-Disposition", "attachment; filename=" + fileName);
Response.Redirect(fileToDownload);
The approaches mentioned in this blog post are all mentioning rendering the file in an iframe but I want the download happen on the client side.
Download File via browser redirect
If you want to download it directly, add the download attribute:
<a class='download-file-link' target='_blank' href='DownloadJsonFile' download="somefilename">

System.InvalidOperationException error when attaching files to System.Net.Mail.MailMessage

I am getting an odd error when attaching one or more files to a System.Net.Mail.MailMessage object from an ASP.NET page.
I create a List(Of Attachment) and add new Attachment objects for each attached file requested by the user. These are files that reside on the web server's file system. For example, the code looks similar to the below, but rather than having hard-coded file paths it's getting them from the database. But while debugging I see that the file paths are valid, pointing to existing files that I can view from Explorer given the full file path or from the website using the virtual address (~/Documents/resume.pdf, for example).
Dim attachments As New List(Of Attachment)
attachments.Add(New Attachment("C:\Websites\Documents\resume.pdf"))
attachments.Add(New Attachment("C:\Websites\Documents\map.png"))
...
After constructing my attachments collection I send the email, adding each Attachment object to the Attachments collection like so:
Dim message As MailMessage = New MailMessage(from, toAddress, subject, body)
If attachments IsNot Nothing Then
For Each att As Attachment In attachments
message.Attachments.Add(att)
Next
End If
Dim mailClient As SmtpClient = New SmtpClient
mailClient.Send(message)
However, when I run the code I get the following error:
System.InvalidOperationException: One of the streams has already been used and can't be reset to the origin.
System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Net.Mail.SmtpException: Failure sending mail. ---> System.InvalidOperationException: One of the streams has already been used and can't be reset to the origin.
at System.Net.Mime.MimePart.ResetStream()
at System.Net.Mail.Attachment.PrepareForSending()
at System.Net.Mail.MailMessage.SetContent()
at System.Net.Mail.MailMessage.Send(BaseWriter writer, Boolean sendEnvelope)
at System.Net.Mail.SmtpClient.Send(MailMessage message)
--- End of inner exception stack trace ---
...
I've tried replacing my logic that adds attachments based on a database query to one that adds a single file with a hard-coded file path. I've tried using different SMTP clients (my web host provider's SMTP server and GMail). I get the same error regardless.
Thanks
Found the answer... the problem was because I was trying to send two separate emails using the same attachments collection.
The email sending logic was in a function that was called like so:
SendEmail(from, to, subject, body, attachments)
If SomethingOrOther Then
SendEmail(from, someoneElse, subject, body, attachments)
End If
My (cheesy) workaround was to just create two attachments lists, one for the first call to SendEmail, another one for the second call.
I think better solution is to set your message object to nothing and your client option to nothing as well, before looping back around for the second message. Good luck!

Updating a page before initiating a download?

I've got a page that allows users to enter search criteria and then display matching records. It also has a download button to enable the user to download matching records.
How can I code it so that clicking on "Download" will first refresh the record display before downloading the data?
This is the code that I'm using for the download:
Response.ClearContent();
Response.ClearHeaders();
using (MemoryStream outputStream = new MemoryStream())
{
// some details elided...
outputStream.Write(documentData, 0, documentData.Count());
string fileName = GenerateFileName();
Response.AppendHeader("content-disposition", String.Format("attachment; filename={0}", fileName));
outputStream.Flush();
outputStream.WriteTo(Response.OutputStream);
}
Response.Flush();
Response.Close();
Only one response you can send back to the browser, ether you update the data, ether you send the new header to start the download.
To make both of them you need to change your steps probably using some javascript and/or ajax call.
How HTTP protocol works: http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html
Construct a javascript method that first updates the page via AJAX, then proceeds to make a non-AJAX request to download the file. As Aristos says, this cannot be done in a single request. A different solution could be to download the file first (non-ajax), then refresh the page without ajax. Normally, javascript code cannot be executed correctly after a new non-ajax request is made, but if it only downloads a file, I think the code might continue its execution to post the next request.

Send XML File to client

I have an XDocument object that needs to be downloaded by the client. This xml will be generated on page_load and then sent to the user as a download.
I cant figgure out how to send the object to the client without having an acctual file.
Any ideas?
As stated i checked this other post not quite the same but close enough.
Response.Clear();
Response.ContentType = "text/xml";
Response.AppendHeader("Content-Disposition","attachment;filename=" + DateTime.Now+".xml");
Response.Write(doc.ToString());
Response.End();

How to save image from remote URL using C# asp.net?

I am working on asp.net C# website in that I getting problem when I try to save image from remote URL.
I have tried with below c# code ...
// C# code
string remoteImageUrl= "http://www.bitpixels.com/getthumbnail?code=83306&url=http://live.indiatimes.com/default.cms?timesnow=1&size=200";
string strRealname = Path.GetFileName(remoteImageUrl);
string exts=Path.GetExtension(remoteImageUrl);
WebClient webClient = new WebClient();
webClient.DownloadFile(remoteImageUrl,Server.MapPath("~/upload/")+strRealname + exts);
When I fetch image from above remoteImageUrl then I getting error "An exception occurred during a WebClient request."
How can I fetch and save remote url image and store it my website upload directory.
or any other way to get remote url image.
I solved that problem The exception comes due to the extension..
When I getting extension of the remoteImageUrl Path.
string exts = Path.GetExtension(remoteImageUrl);
string strRealname = Path.GetFileName(remoteImageUrl);
It returns ".cms" so exception throws at that point,
I avoid the ".cms" extension from the remoteImageURL and then call
WebClient webClient = new WebClient();
webClient.DownloadFile(remoteImageUrl,Server.MapPath("~/upload/")+strRealname + exts);
It works fine.
Yout code is just fine. Make sure your application pool identity, has access to "upload" folder with write access.
And if you are using a proxy server you should also specify this in web.config file.
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true"></defaultProxy>
</system.net>
Are you running under anything less than full trust? If so, you can't make arbitrary web requests either.

Resources