I have this in my Account Controller Register:
var token = WebSecurity.CreateUserAndAccount(
model.UserName,
model.Password,
new
{
model.Email
},
true);
var confirmationUrl = System.Web.HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) +
"/Account/ConfirmAccount/" + token;
dynamic email = new Email("RegisterConfirmation");
email.To = model.Email;
email.UserName = model.UserName;
email.ConfirmationUrl = confirmationUrl;
email.Send();
Usually i expect that to send out a link to emails and its doing so when sent to a GMail and Yahoo account, but when sent to aHotmail account the link is sent as a plain string which would require copy and past to navigate there.
Any ideas on what's causing this?
I would expect its something to do with hotmail.
If you want, you can instead flag the email as html (email.IsHtml= true I believe) and write it in html, which should work with everything.
Related
I am using sendgrid with a .NET Core site I built. It has a contact form on it so a client can fill out the form and it is sent to my email address. I am using the Sendgrid nuget package to generate and send the email. The issue is that when I get the email I dont want to replyto myself and when I make the replyto equal the email address entered - sendgrid wont send the email because that email isnt entered into the Single Sender Verification. There must be a way to configure things so in my email when I click reply it will go to the person who sent the email. Right?
string key = _iConfig.GetSection("Email").GetSection("SendGridKey").Value;
var client = new SendGridClient(key);
var subject = "Form submission";
var fromemail = _iConfig.GetSection("Email").GetSection("From").Value;
var from = new EmailAddress(fromemail, model.Name);
var toemail = _iConfig.GetSection("Email").GetSection("To").Value;
var to = new EmailAddress(toemail, "Admin");
var htmlContent = "<strong>From: " + model.Name + "<br>Email: " + model.Email + "<br>Message: " + model.Message;
var msg = MailHelper.CreateSingleEmail(from, to, subject, model.Message, htmlContent);
var response = await client.SendEmailAsync(msg);
return response.IsSuccessStatusCode;
Twilio SendGrid developer evangelist here.
To set the reply-to address in C# you need the setReplyTo method, like this:
var msg = MailHelper.CreateSingleEmail(from, to, subject, model.Message, htmlContent);
// Add the reply-to email address here.
var replyTo = new EmailAddress(model.Email, model.Name);
msg.setReplyTo(replyTo);
var response = await client.SendEmailAsync(msg);
return response.IsSuccessStatusCode;
I am developing a site where the users will be able to click a "Forgot My Password" button to reset their passwords.
Currently, once the email has been validated, the following code should generate a token to be emailed to the user:
if(validUser != null)
{
var generationTime = DateTime.Now;
var pwToken = await _userManager.GeneratePasswordResetTokenAsync(validUser);
await _userManager.UpdateAsync(validUser);
var url = $"https://{Request.Host}/verify/{HttpUtility.UrlEncode(pwToken)}";
//EmailHelper.SendMagicLinkEmail(validUser, url, Request);
return new RedirectResult("/");
}
All information online regarding this seems to suggest that this is the way to do things. I have set up the Default token providers in the Startup.csfile too:
identityOptions: o => {
o.User.RequireUniqueEmail = true;
o.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultProvider;
o.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultProvider;
},
Yet when a token is generated it produces a large token such as this:
CfDJ8CnvAYtZf+1IjXpKUM7+umDYEaImg2SPFglPX3Y8RmYpEfg5zpK8xL54lvlbJUd54CaIzzYlff/GU+xKKS8mmG5UdC1zdk24nOsJNpIlmC3P5V72BchS4P9DGFTR77XiKbMAAYymnMomS2zCdTKh+E4bn9RI6FVinMecG1HR7nSHmOI2McbXHBFTanI/0uwxH5WI/Dj4AFTBP39ni7mfKkeWz2nJ5pTemELJJ6pYP50+
The problem here is obviously the forward slashes, which cause issues with routing so are encoded out here:
var url = $"https://{Request.Host}/verify/{HttpUtility.UrlEncode(pwToken)}";
The problem is that even with that, .Net Core seems to un-encode it and produce the following error when the generated link is accessed:
This error isn't necessarily the issue, and I do understand it's importance. Yet I can't seem to find any explanation as to why this token is behaving this way. All online examples seem to produce a fairly standard GUID style token, not something such as this.
Does anyone know why this might be happening?
Cheers
You may want to try the Url.Action() method:
Example:
var token = userManager.GeneratePasswordResetTokenAsync(user).Result;
var resetLink = Url.Action("ResetPassword","Account", new { token = token }, protocol: HttpContext.Request.Scheme);
var message = "Click here to reset your password";
//Then send your message to the user
Note in the example above the email must be HTML for the link to work
The token looks fairly normal to me.
I think the URL encoding method you'd want to use is Uri.EscapeDataString. What I've personally done is using a UriBuilder and escaped the query string values (in this case for email confirmation):
var uriBuilder = new UriBuilder
{
Scheme = "https",
Host = "my.website.com",
Path = "/confirmEmail",
Query = $"email={Uri.EscapeDataString(email)}&token={Uri.EscapeDataString(token)}"
};
var fullUrl = uriBuilder.Uri.AbsoluteUri;
For you that'd be:
var uriBuilder = new UriBuilder
{
Scheme = "https",
Host = Request.Host,
Path = $"/verify/{Uri.EscapeDataString(pwToken)}"
};
var fullUrl = uriBuilder.Uri.AbsoluteUri;
I'm hey one of the most weirdest problems i have seen until now. I have the same peace of code the SMTP client. I have it in a separate class that handles sending emails so this is the constructor`
// Setting the smtp info
smtpClient = new SmtpClient("xxxxxxx", 587);
// Setting the no reply email address
smtpClient.Credentials = new NetworkCredential("xxxxxxxxx", "xxxxx");
FromMailAddress = new MailAddress("xxxxxxxxx", "xxxxxxxx");
// Setting Ssl
smtpClient.EnableSsl = true;`
And this is for sending the Email:
// Setting a new email address for the recver
MailAddress reciver = new MailAddress("xxxxxxxx");
// Creating a new Email message
MailMessage email = new MailMessage();
email.IsBodyHtml = true;
email.To.Add(reciver);
email.From = FromMailAddress;
email.Subject = "Email confomation link";
email.Body = "Please Fonfurm your email by pressing this link: link";
smtpClient.Send(email);
Sorry i really needed to block out some stuff. But this code works in a test application that i made in just simple comandline C# application. Now comes the strange thing when i call it in a simple ActionResult that i created for this it works but when i call it in Register method it fails it says time out, and for the rest it does not give anymore information. Here is the test method i created:
public ActionResult SendTestEmail()
{
new EmailManager().SendEmailConfirmation("xxxxxxxx", "Hello world");
return RedirectToAction("Index");
}
Quite simple and it works but when i put it like this it fails:
public async Task<ActionResult> Register(RegisterViewModel model)
{
// Check if model is valled And if we have a id
if (ModelState.IsValid && !String.IsNullOrEmpty(model.RegisterCode))
{
ApplicationUser user = new ApplicationUser { UserName = model.UserName, Email = model.Email.ToLower() };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
// Sing in
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
// Add the members role to the user
UserManager.AddToRole(user.Id, "Member");
// Createing a token for email confermation
string emailCode = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// Createing a URL
string callbackUrl = Url.Action(
"ConfirmEmail",
"Account",
new { userId = user.Id, code = emailCode },
protocol: Request.Url.Scheme
);
// Sending the email
new EmailManager().SendEmailConfirmation(model.Email, callbackUrl);
// delete the registion code form the database
GenerateCodeManager.DeleteFromCodeFromDatabase(model.RegisterCode);
// Return to index
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
return View(model);
}
And than we have a problem it fails. I really dont know why i think this also might the problem why my web server is also not sending emails. i use the SMTP of zoho That is this SMTP smtp.zoho.eu Like i said it works but not in this method.
I am trying to send email with SendGrid to multiple recipients in an ASP.Net C# web application
According to the SendGrid documentation I need to add X-SMTPAPI header to my message in JSON formatted string. I do so, for first check I just added a hand-typed string before building my json email list progamatically here is my code:
string header = "{\"to\": [\"emailaddress2\",\"emailaddress3\"], \"sub\": { \"%name%\": [\"Ben\",\"Joe\"]},\"filters\": { \"footer\": { \"settings\": { \"enable\": 1,\"text/plain\": \"Thank you for your business\"}}}}";
string header2 = Regex.Replace(header, "(.{72})", "$1" + Environment.NewLine);
var myMessage3 = new SendGridMessage();
myMessage3.From = new MailAddress("emailaddress1", "FromName");
myMessage3.Headers.Add("X-SMTPAPI", header2);
myMessage3.AddTo("emailaddress4");
myMessage3.Subject = "Test subject";
myMessage3.Html = "Test message";
myMessage3.EnableClickTracking(true);
// Create credentials, specifying your user name and password.
var credentials = new NetworkCredential(ConfigurationManager.AppSettings["xxxxx"], ConfigurationManager.AppSettings["xxxxx"]);
// Create an Web transport for sending email.
var transportWeb = new Web(credentials);
// Send the email, which returns an awaitable task.
transportWeb.DeliverAsync(myMessage3);
But it just seems to ignore my header, and sends the email to the one email "emailaddress4" used in "addto".
According the documentation if the header JSON is parsed wrongly, then SendGrid sends an email about the error to the email address set in "FROM" field, but I get no email about any error.
Anyone got any idea?
For me using the latest 9.x c# library the only way I could solve this was by using the MailHelper static functions like this:
var client = new SendGridClient(HttpClient, new SendGridClientOptions { ApiKey = _sendGridApiKey, HttpErrorAsException = true });
SendGridMessage mailMsg;
var recipients = to.Split(',').Select((email) => new EmailAddress(email)).ToList();
if (recipients.Count() > 1)
{
mailMsg = MailHelper.CreateSingleEmailToMultipleRecipients(
new EmailAddress(from),
recipients,
subject,
"",
body);
}
else
{
mailMsg = MailHelper.CreateSingleEmail(
new EmailAddress(from),
recipients.First(),
subject,
"",
body);
}
if (attachment != null)
{
mailMsg.AddAttachment(attachment.Name,
attachment.ContentStream.ToBase64(),
attachment.ContentType.MediaType);
}
var response = await client.SendEmailAsync(mailMsg).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
_log.Trace($"'{subject}' email to '{to}' queued");
return true;
}
else {
throw new HttpRequestException($"'{subject}' email to '{to}' not queued");
}
I'm not sure why you wouldn't recieve any errors at your FROM address, but your JSON contains the following flaws:
, near the end makes the string invalid json
spaces around the first % in %name%, that might make sendgrid think it's an invalid substitution tag
if you use the X-SMTPAPI header to specify multiple recipients, you are not supposed to add a standard SMTP TO using AddTo().
Besides that, you didn't wrap the header at 72 characters (see the example in the documentation).
I figured that however the X-SMTPAPI documentation talks about passing the header as JSON, the API itself expects it as a parameter, containing Ienumerable string. So the working code is:
var myMessage3 = new SendGridMessage();
myMessage3.From = new MailAddress("email4#email.com", "Test Sender");
myMessage3.AddTo("email2#email.com");
myMessage3.Subject = "Új klubkártya regisztrálva";
myMessage3.Html = "Teszt üzenet";
myMessage3.EnableClickTracking(true);
/* SMTP API
* ===================================================*/
// Recipients
var addresses = new[]{
"email2#email.com", "email3#email.com"
};
//string check = string.Join(",", addresses);
myMessage3.Header.SetTo(addresses);
// Create credentials, specifying your user name and password.
var credentials = new NetworkCredential(ConfigurationManager.AppSettings["xxxxxxx"], ConfigurationManager.AppSettings["xxxxxxxxx"]);
// Create an Web transport for sending email.
var transportWeb = new Web(credentials);
// Send the email, which returns an awaitable task.
transportWeb.DeliverAsync(myMessage3);
I'm new in asp.net. I'm building a web-based application with C#, and I thought a lot about how to authenticate the user by his ID using the email.
I searched about it and I tried this code but it didn't worked because it sends a page rather than link with ID.
string URI = "http://localhost:49496/Activated.aspx";
string myParameters = "param1="+id.Text;
string HtmlResult = "";
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
HtmlResult = wc.UploadString(URI, myParameters);
}
MailMessage o = new MailMessage("f#hotmail.com", EMPemail, "KAUH Account Activation", "Hello, " + name + "<br /> Your KAUH Account about to activate click the link below to complete the activation process <br />" + HtmlResult);
NetworkCredential netCred = new NetworkCredential("f#hotmail.com", "______");
SmtpClient smtpobj = new SmtpClient("smtp.live.com", 587);
smtpobj.EnableSsl = true;
o.IsBodyHtml = true;
smtpobj.Credentials = netCred;
smtpobj.Send(o);
I need the ID in the activation page to change the "Activated" column from NO to YES.
Now my question: is the idea to authenticate the user by sending the ID secure?if it is,How can I perform it?
Best way to authenticate the user
You can easily create a 'secure' authentication by creating a hash, with for example MD5 or SHA1. The information you hash could be, for example, appending the e-mail and user ID as a string. You can save the hash inside the database for fast comparision (that you do when the user clicks the link with the hash you created). When the hash is inside the database, the authentication is complete.
You could also append the e-mail to the link, so you are 99.9999% sure. This is, however, not really needed as the end user does not know the ID.
Sending the page instead of the link issue
You are adding the HtmlResult that contains the content of the page you requested with wc.UploadString. Create the link inside the e-mail body manually using HTML:
MailMessage o = new MailMessage("f2#hotmail.com", EMPemail, "KAUH Account Activation", "Hello, " + name + "<br /> Your KAUH Account about to activate click the link below to complete the activation process <br />Click here");
Firstly I would definitely look at encrypting the ID that you will have in the URL. Just leaving the ID blank can leave you vulnerable to attacks.
Also if your body is html you should be able to add the link in the body with something similar:
string sURL= "http://localhost:49496/Activated.aspx?sID=" + Uri.EscapeDataString(id.Text);
then add the following to your HTML body:
<a style='text-decoration: none; font-weight: bold;' href='" + sURL+ "'>Click Here to Activate</a>
and to get the ID in the activation.aspx.cs page:
string sID = Uri.UnescapeDataString(Request.QueryString["sID"]);