How to use Windows task Scheduler in ASP.NET - asp.net

I am trying to use ASP.NET in Window Task Scheduler. I want to send the email on specific time.
But ASP.NET is not run as an EXE, it has a dynamic ip address.
I have no idea to use Window Task Scheduler in ASP.NET.
Can you give me any solutions for it?
void SendEmail()
{
//get the data from database
DataTable data = GetData();
DataTable email_data = GetEmailData();
//set DataTable Name of Excel Sheet
data.TableName = "NSOList";
//Create a New Workook
using (XLWorkbook wb = new XLWorkbook())
{
//Add the DataTable as Excel Workhseet
wb.Worksheets.Add(data);
using (MemoryStream memoryStream = new MemoryStream())
{
//Save the Excel Workbook to MemoryStream
wb.SaveAs(memoryStream);
//Convert MemoryStream to Byte array
byte[] bytes = memoryStream.ToArray();
memoryStream.Close();
//body with embedded image
AlternateView body = AlternateView.CreateAlternateViewFromString
("Hi <br><br> <img src=cid:example>", null, "text/html");
//create the LinkedResource (embedded image)
LinkedResource image = new LinkedResource("c:\\example.png");
image.ContentId = "example";
//add the LinkedResource to the appropriate view
body.LinkedResources.Add(image);
String from = "abcd#abcd.net";
//bring Email data
for (int i = 0; i < email_data.Rows.Count; i++)
{
String to = email_data.Rows[i][0].ToString();
using (MailMessage mm = new MailMessage(from, to))
{
SmtpClient smtp = new SmtpClient();
mm.Subject = "List";
mm.AlternateViews.Add(body);
mm.Attachments.Add(new Attachment(new MemoryStream(bytes), "NSOList.xlsx"));
mm.IsBodyHtml = true;
smtp.Host = "smtp.gmail.com";
smtp.EnableSsl = true;
System.Net.NetworkCredential credentials = new System.Net.NetworkCredential();
credentials.UserName = "abcd#gmail.com";
credentials.Password = "abcd";
smtp.UseDefaultCredentials = true;
smtp.Credentials = credentials;
smtp.Port = 587;
smtp.Send(mm);
}
}
}
}
}

You should use a Task Scheduler like Quartz.Net. It allows you to define classes as Jobs, and then execute those jobs according to an schedule. I'm currently using it in some in-house projects and it performs as advertised.
EDITED
Check the answers here.

It should be a console application with your code in it. In bin folder it will create a .exe file which you need to use it in windows task scheduler.
Following link provides you a step by step procedure on how to create a task in windows task scheduler.
http://www.digitalcitizen.life/how-create-task-basic-task-wizard

Related

Strange exception testing EmailSender

I have just closely followed all MS instructions on scaffolding the Identity UI in an ASP.NET Core 3.0 MVC app. If I run the project, it opens the default home page fine, and links on that page respond well. Yet a simple integration test fails with an exception.
The single method in the EmailSender looks like this:
public Task SendEmailAsync(string email, string subject, string htmlMessage)
{
using (var client = new SmtpClient())
using (var msg = new MailMessage())
{
msg.From = new MailAddress("system#timekeeper.co.za");
msg.To.Add(new MailAddress(email));
msg.Subject = subject;
msg.IsBodyHtml = true;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("timekeeper#somewhere.com", "something");
client.Host = "mail.myhost.com";
client.Port = 25;
return client.SendMailAsync(msg);
}
}
and my test looks like this:
[TestMethod]
public async Task Send_Email()
{
var sender = new EmailSender();
await sender.SendEmailAsync("somebody#somewhere.net", "Test Mail", "This is a test");
Assert.IsTrue(true);
}
When I run the test it fails with the following exception:
Test method TimeKeeper.Tests.Integration.EmailSEnderTests.Send_Email threw exception:
System.Threading.Tasks.TaskCanceledException: A task was canceled.
at TimeKeeper.Tests.Integration.EmailSEnderTests.Send_Email() in D:\Dev\RestServices\TimeKeeper.Tests.Integration\EmailSEnderTests.cs:line 15
at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.ThreadOperations.ExecuteWithAbortSafety(Action action)
await the task instead of returning it.
public async Task SendEmailAsync(string email, string subject, string htmlMessage) {
using (var client = new SmtpClient())
using (var msg = new MailMessage()) {
msg.From = new MailAddress("system#timekeeper.co.za");
msg.To.Add(new MailAddress(email));
msg.Subject = subject;
msg.IsBodyHtml = true;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("timekeeper#somewhere.com", "something");
client.Host = "mail.myhost.com";
client.Port = 25;
await client.SendMailAsync(msg); //<-- await completion
}
}
Chances are that the client is being disposed before it has a chance to complete sending the email.
You should also take note of the warnings in documentation about using the now obsolete SmtpClient for new development.
DE0005: SmtpClient shouldn't be used
Motivation
SmtpClient doesn't support many modern protocols. It is compat-only. It's great for one off emails from tools, but doesn't
scale to modern requirements of the protocol.
Recommendation
Use MailKit or other libraries.

files not uploading to FTP Server [duplicate]

I try upload a file to an FTP-server with C#. The file is uploaded but with zero bytes.
private void button2_Click(object sender, EventArgs e)
{
var dirPath = #"C:/Documents and Settings/sander.GD/Bureaublad/test/";
ftp ftpClient = new ftp("ftp://example.com/", "username", "password");
string[] files = Directory.GetFiles(dirPath,"*.*");
var uploadPath = "/httpdocs/album";
foreach (string file in files)
{
ftpClient.createDirectory("/test");
ftpClient.upload(uploadPath + "/" + Path.GetFileName(file), file);
}
if (string.IsNullOrEmpty(txtnaam.Text))
{
MessageBox.Show("Gelieve uw naam in te geven !");
}
}
The existing answers are valid, but why re-invent the wheel and bother with lower level WebRequest types while WebClient already implements FTP uploading neatly:
using (var client = new WebClient())
{
client.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
client.UploadFile("ftp://host/path.zip", WebRequestMethods.Ftp.UploadFile, localFile);
}
Easiest way
The most trivial way to upload a file to an FTP server using .NET framework is using WebClient.UploadFile method:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
var url = "ftp://ftp.example.com/remote/path/file.zip";
client.UploadFile(url, #"C:\local\path\file.zip");
Advanced options
If you need a greater control, that WebClient does not offer (like TLS/SSL encryption, ascii/text transfer mode, active mode, transfer resuming, progress monitoring, etc), use FtpWebRequest. Easy way is to just copy a FileStream to an FTP stream using Stream.CopyTo:
var url = "ftp://ftp.example.com/remote/path/file.zip";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
fileStream.CopyTo(ftpStream);
}
Progress monitoring
If you need to monitor an upload progress, you have to copy the contents by chunks yourself:
var url = "ftp://ftp.example.com/remote/path/file.zip";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(url);
request.Credentials = new NetworkCredential("username", "password");
request.Method = WebRequestMethods.Ftp.UploadFile;
using (Stream fileStream = File.OpenRead(#"C:\local\path\file.zip"))
using (Stream ftpStream = request.GetRequestStream())
{
byte[] buffer = new byte[10240];
int read;
while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
ftpStream.Write(buffer, 0, read);
Console.WriteLine("Uploaded {0} bytes", fileStream.Position);
}
}
For GUI progress (WinForms ProgressBar), see C# example at:
How can we show progress bar for upload with FtpWebRequest
Uploading folder
If you want to upload all files from a folder, see
Upload directory of files to FTP server using WebClient.
For a recursive upload, see
Recursive upload to FTP server in C#
.NET 5 Guide
async Task<FtpStatusCode> FtpFileUploadAsync(string ftpUrl, string userName, string password, string filePath)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(userName, password);
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using (Stream requestStream = request.GetRequestStream())
{
await fileStream.CopyToAsync(requestStream);
}
using (FtpWebResponse response = (FtpWebResponse)await request.GetResponseAsync())
{
return response.StatusCode;
}
}
.NET Framework
public void UploadFtpFile(string folderName, string fileName)
{
FtpWebRequest request;
string folderName;
string fileName;
string absoluteFileName = Path.GetFileName(fileName);
request = WebRequest.Create(new Uri(string.Format(#"ftp://{0}/{1}/{2}", "127.0.0.1", folderName, absoluteFileName))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = 1;
request.UsePassive = 1;
request.KeepAlive = 1;
request.Credentials = new NetworkCredential(user, pass);
request.ConnectionGroupName = "group";
using (FileStream fs = File.OpenRead(fileName))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Flush();
requestStream.Close();
}
}
How to use
UploadFtpFile("testFolder", "E:\\filesToUpload\\test.img");
use this in your foreach
and you only need to create folder one time
to create a folder
request = WebRequest.Create(new Uri(string.Format(#"ftp://{0}/{1}/", "127.0.0.1", "testFolder"))) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)request.GetResponse();
The following works for me:
public virtual void Send(string fileName, byte[] file)
{
ByteArrayToFile(fileName, file);
var request = (FtpWebRequest) WebRequest.Create(new Uri(ServerUrl + fileName));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UsePassive = false;
request.Credentials = new NetworkCredential(UserName, Password);
request.ContentLength = file.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(file, 0, file.Length);
requestStream.Close();
var response = (FtpWebResponse) request.GetResponse();
if (response != null)
response.Close();
}
You can't read send the file parameter in your code as it is only the filename.
Use the following:
byte[] bytes = File.ReadAllBytes(dir + file);
To get the file so you can pass it to the Send method.
public static void UploadFileToFtp(string url, string filePath, string username, string password)
{
var fileName = Path.GetFileName(filePath);
var request = (FtpWebRequest)WebRequest.Create(url + fileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
using (var fileStream = File.OpenRead(filePath))
{
using (var requestStream = request.GetRequestStream())
{
fileStream.CopyTo(requestStream);
requestStream.Close();
}
}
var response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload done: {0}", response.StatusDescription);
response.Close();
}
In the first example must change those to:
requestStream.Flush();
requestStream.Close();
First flush and after that close.
This works for me,this method will SFTP a file to a location within your network.
It uses SSH.NET.2013.4.7 library.One can just download it for free.
//Secure FTP
public void SecureFTPUploadFile(string destinationHost,int port,string username,string password,string source,string destination)
{
ConnectionInfo ConnNfo = new ConnectionInfo(destinationHost, port, username, new PasswordAuthenticationMethod(username, password));
var temp = destination.Split('/');
string destinationFileName = temp[temp.Count() - 1];
string parentDirectory = destination.Remove(destination.Length - (destinationFileName.Length + 1), destinationFileName.Length + 1);
using (var sshclient = new SshClient(ConnNfo))
{
sshclient.Connect();
using (var cmd = sshclient.CreateCommand("mkdir -p " + parentDirectory + " && chmod +rw " + parentDirectory))
{
cmd.Execute();
}
sshclient.Disconnect();
}
using (var sftp = new SftpClient(ConnNfo))
{
sftp.Connect();
sftp.ChangeDirectory(parentDirectory);
using (var uplfileStream = System.IO.File.OpenRead(source))
{
sftp.UploadFile(uplfileStream, destinationFileName, true);
}
sftp.Disconnect();
}
}
publish date: 06/26/2018
https://learn.microsoft.com/en-us/dotnet/framework/network-programming/how-to-upload-files-with-ftp
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Get the object used to communicate with the server.
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://www.contoso.com/test.htm");
request.Method = WebRequestMethods.Ftp.UploadFile;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential("anonymous",
"janeDoe#contoso.com");
// Copy the contents of the file to the request stream.
byte[] fileContents;
using (StreamReader sourceStream = new StreamReader("testfile.txt"))
{
fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
}
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine($"Upload File Complete, status
{response.StatusDescription}");
}
}
}
}
Best way I've found is FluentFtp
You can find the repo here:
https://github.com/robinrodricks/FluentFTP
and the quickstart example here:
https://github.com/robinrodricks/FluentFTP/wiki/Quick-Start-Example.
And actually the WebRequest class recommended by a few people here, is not recommended by Microsoft anymore, check out this page:
https://learn.microsoft.com/en-us/dotnet/api/system.net.webrequest?view=net-5.0
// create an FTP client and specify the host, username and password
// (delete the credentials to use the "anonymous" account)
FtpClient client = new FtpClient("123.123.123.123", "david", "pass123");
// connect to the server and automatically detect working FTP settings
client.AutoConnect();
// upload a file and retry 3 times before giving up
client.RetryAttempts = 3;
client.UploadFile(#"C:\MyVideo.mp4", "/htdocs/big.txt",
FtpRemoteExists.Overwrite, false, FtpVerify.Retry);
// disconnect! good bye!
client.Disconnect();
I have observed that -
FtpwebRequest is missing.
As the target is FTP, so the NetworkCredential required.
I have prepared a method that works like this, you can replace the value of the variable ftpurl with the parameter TargetDestinationPath. I had tested this method on winforms application :
private void UploadProfileImage(string TargetFileName, string TargetDestinationPath, string FiletoUpload)
{
//Get the Image Destination path
string imageName = TargetFileName; //you can comment this
string imgPath = TargetDestinationPath;
string ftpurl = "ftp://downloads.abc.com/downloads.abc.com/MobileApps/SystemImages/ProfileImages/" + imgPath;
string ftpusername = krayknot_DAL.clsGlobal.FTPUsername;
string ftppassword = krayknot_DAL.clsGlobal.FTPPassword;
string fileurl = FiletoUpload;
FtpWebRequest ftpClient = (FtpWebRequest)FtpWebRequest.Create(ftpurl);
ftpClient.Credentials = new System.Net.NetworkCredential(ftpusername, ftppassword);
ftpClient.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
ftpClient.UseBinary = true;
ftpClient.KeepAlive = true;
System.IO.FileInfo fi = new System.IO.FileInfo(fileurl);
ftpClient.ContentLength = fi.Length;
byte[] buffer = new byte[4097];
int bytes = 0;
int total_bytes = (int)fi.Length;
System.IO.FileStream fs = fi.OpenRead();
System.IO.Stream rs = ftpClient.GetRequestStream();
while (total_bytes > 0)
{
bytes = fs.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
//fs.Flush();
fs.Close();
rs.Close();
FtpWebResponse uploadResponse = (FtpWebResponse)ftpClient.GetResponse();
string value = uploadResponse.StatusDescription;
uploadResponse.Close();
}
Let me know in case of any issue, or here is one more link that can help you:
https://msdn.microsoft.com/en-us/library/ms229715(v=vs.110).aspx

Mail excel attachment in asp.net C#

I am trying to attach a excel file with mail, but not getting where I am doing the mistake. There is no error coming but mail does not get send. When I try to check the server path of file with file exist. it show me true, so my file path is correct.
Mail is going properly without attachment.
MailMessage Msg = new MailMessage();
Msg.Subject = "User Creation";
string body = MailSending.PrepareMailBodyWith("WelcomeTemplate.htm", "LoginID", LoginID, "password", password);
string clientCoverage = System.Web.HttpContext.Current.Server.MapPath("~/file/abc.xlsx");
bool isFile = false;
if (File.Exists(clientCoverage))
{
isFile = true;
}
byte[] bytes = System.IO.File.ReadAllBytes(clientCoverage);
MemoryStream stream = new MemoryStream(bytes);
lblerror.Text = avnTutorial + isFile.ToString() ;
Attachment attachment = new Attachment(stream, "document.xlsx");
Msg.Attachments.Add(attachment);
Msg.Body = body;
Msg.IsBodyHtml = true;
Msg.From = new MailAddress("info#xyz.in");
Msg.To.Add(new MailAddress(Email));
SmtpClient client = new SmtpClient();
client.Host = "mail.xyz.in";
client.Port = 25;
client.Credentials = new System.Net.NetworkCredential("info#xyz.in", "xyz");
client.Send(Msg);
I tried with without memory stream also here is the code but does not work.
Attachment attachment = new Attachment(clientCoverage, MediaTypeNames.Application.Octet);

how to send image as attachment with web service?

I want to add new employee to web service.
The employee photo should be sent as an attachment with the web service.
and sent as a password protected ZIP file.
Create a class for your image and send as a stream as follows,
You have to add the stream conversion for each image and add the details to a list.
in the client side.
Stream stream = (Stream)openDialog.File.OpenRead();
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
BitmapImage bmi = new BitmapImage();
using (MemoryStream ms = new MemoryStream(bytes))
{
bmi.SetSource(ms);
newRow.Thumbnail = bmi;
}
in your service side
string filePath = ConfigurationManager.AppSettings.Get("ImageUploadPath");
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
filePath = filePath + "\\" + picture.FileName + "." + picture.FileType;
if (picture.FileName != string.Empty)
{
fileStream = File.Open(filePath, FileMode.Create);
writer = new BinaryWriter(fileStream);
writer.Write(picture.FileStream);
}

Sending mass email in ASP.NET

This is my code to send lots of emails. I want to optimize this code to be sure that it will work and can successfully send all emails. What should I do? I know that putting interrupts between sending might be useful but how can I do this?
The main problem is avoiding classify emails as spam and decreasing number of failed sent emails.
var list = from c in context.Emails orderby c.EmailAddress select c.EmailAddress;
MailMessage mail = new MailMessage();
try
{
mail.From = new MailAddress(txtfrom.Text);
foreach (var c in list)
{
mail.To.Add(new MailAddress(c.ToString()));
}
mail.Subject = txtSub.Text;
mail.IsBodyHtml = true;
mail.Body = txtBody.Text;
if (FileUpload1.HasFile)
{
mail.Attachments.Add(new Attachment(
FileUpload1.PostedFile.InputStream, FileUpload1.FileName));
}
SmtpClient smtp = new SmtpClient();
smtp.Send(mail);
}
catch (Exception)
{
//exception handling
}
I would advise you against adding all reciepients into the same mail message.
Rather use this code:
mail.From = new MailAddress(txtfrom.Text);
mail.Subject = txtSub.Text;
mail.IsBodyHtml = true;
mail.Body = txtBody.Text;
if (FileUpload1.HasFile)
{
mail.Attachments.Add(new Attachment(FileUpload1.PostedFile.InputStream, FileUpload1.FileName));
}
SmtpClient smtp = new SmtpClient();
foreach (var c in list)
{
mail.To.Clear();
mail.To.Add(new MailAddress(c.ToString()));
smtp.Send(mail);
}
With a little due diligence, this can be accomplished with a very simple console application which can be called from the Web form to dispatch the emails. By diligence, I mean to insert a pause between batches so that the mail server won't get bogged down. For example, if you were grabbing the addresses from a DB and sending them out, you could have something like:
if ((count >= 100) && (count % 100 == 0))
Thread.Sleep(30000);
-----------------------------------------
// Web form code-behind
// Pass subject and message strings as params to console app
ProcessStartInfo info = new ProcessStartInfo();
string arguments = String.Format(#"""{0}"" ""{1}""",
subjectText.Text.Replace(#"""", #""""""),
messageText.Text.Replace(#"""", #""""""));
info.FileName = MAILER_FILEPATH;
Process process = Process.Start(info.FileName, arguments);
Process.Start(info);
More info here: Calling Console Application from Web Form

Resources