postal
I encountered this error message "Value cannot be null. Parameter name: httpContext" when I tried to send email by using Postal.mvc5.
This error happened when tried to call Postal.EmailService.CreateMailMessage(Email email).
Anyone one can help on this? Thanks.
The following are the error details.
at System.Web.HttpContextWrapper..ctor(HttpContext httpContext)
at System.Web.Optimization.Styles.get_Context()
at System.Web.Optimization.Styles.get_Manager()
at System.Web.Optimization.Styles.RenderFormat(String tagFormat, String[] paths)
at System.Web.Optimization.Styles.Render(String[] paths)
at ASP._Page_Views_Shared__Layout_cshtml.Execute() in c:\XXX\Views\Shared\_Layout.cshtml:line 19
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer)
at System.Web.WebPages.WebPageBase.<>c__DisplayClass3.<RenderPageCore>b__2(TextWriter writer)
at System.Web.WebPages.HelperResult.WriteTo(TextWriter writer)
at System.Web.WebPages.WebPageExecutingBase.WriteTo(TextWriter writer, HelperResult content)
at System.Web.WebPages.WebPageBase.Write(HelperResult result)
at System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body)
at System.Web.WebPages.WebPageBase.PopContext()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at Postal.EmailViewRenderer.RenderView(IView view, ViewDataDictionary viewData, ControllerContext controllerContext, ImageEmbedder imageEmbedder)
at Postal.EmailViewRenderer.Render(Email email, String viewName)
at Postal.EmailService.CreateMailMessage(Email email)
ForgotPassword trigger send email via Email Helper:
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist or is not confirmed
return View("ForgotPasswordConfirmation");
}
// Check if email confirm required
if (CacheHelper.Settings.EmailConfirmedRequired && !(await UserManager.IsEmailConfirmedAsync(user.Id)))
{
return View("ForgotPasswordConfirmation");
}
string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
var emailTemplateQuery = await _emailTemplateService.Query(x => x.Slug.ToLower() == "forgotpassword").SelectAsync();
var emailTemplate = emailTemplateQuery.Single();
dynamic email = new Postal.Email("Email");
email.To = CacheHelper.Settings.EmailContact;
email.From = CacheHelper.Settings.EmailContact;
email.Subject = emailTemplate.Subject;
email.Body = emailTemplate.Body;
email.CallbackUrl = callbackUrl;
EmailHelper.SendEmail(email);
return RedirectToAction("ForgotPasswordConfirmation", "Account");
}
// If we got this far, something failed, redisplay form
return View(model);
}
Email Helper class:
Error encountered in EmailService.CreateMailMessage(email);
public static IEmailService EmailService = Postal.Email.CreateEmailService();
public static void SendEmail(Email email, bool preMailer = true)
{
Task.Factory.StartNew(() =>
{
try
{
//skip email if there is no settings
if (string.IsNullOrEmpty(CacheHelper.Settings.SmtpHost) && string.IsNullOrEmpty(CacheHelper.Settings.SmtpPassword))
return;
//Error encountered when call create mail message
var message = EmailService.CreateMailMessage(email);
using (var smtpClient = new SmtpClient())
{
smtpClient.UseDefaultCredentials = false;
// set credential if there is one
if (!string.IsNullOrEmpty(CacheHelper.Settings.SmtpUserName) && !string.IsNullOrEmpty(CacheHelper.Settings.SmtpPassword))
{
var credential = new NetworkCredential
{
UserName = CacheHelper.Settings.SmtpUserName,
Password = CacheHelper.Settings.SmtpPassword
};
smtpClient.Credentials = credential;
}
smtpClient.Host = CacheHelper.Settings.SmtpHost;
smtpClient.EnableSsl = CacheHelper.Settings.SmtpSSL;
if (CacheHelper.Settings.SmtpPort.HasValue)
smtpClient.Port = CacheHelper.Settings.SmtpPort.Value;
//moving CSS to inline style attributes, to gain maximum E-mail client compatibility.
if (preMailer)
message.Body = PreMailer.Net.PreMailer.MoveCssInline(message.Body).Html;
smtpClient.Send(message);
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
});
}
Source: (StackOverflow)
I'm trying to find a solution on how to send an email to multiple Hospital email addresses depending on which orders are linked to the Delivery that the change is being made on - using Postal.
So for a bit of context, I wish to send the same email to all the Hospitals that have orders linked to a delivery. So upon editing a delivery, (to change the status
for example), an email must be sent to ALL the hospitals that have Orders in that Delivery.
The issue is that a Delivery can have many orders and not necessarily just one, and because of that, I'm not sure how to target all the email addresses of all the hospitals that have Orders in that specific Delivery.
Also, a Hospital is only linked to an Order and an Order is linked to a Delivery - and the only way to access the hospital's email is from the Hospital
table. Which means I have to go through the Order
table and then to the Hospital
table.
How would I go about doing this? I'm still pretty new to MVC, so I will appreciate all the help I can get.
I'm doing this in the POST of my Edit Method in the Delivery Controller because I only wish to send an email from there after an Edit has been made. Hence why I call it after the savechanges()
.
These linesOrder order = db.Orders.Where(o => o.OrderID == order.DeliveryID).FirstOrDefault();
and Hospital hospital = db.Hospitals.(h => h.HospitalID == order.HospitalID);
are just my attempts. They don't work, and are not part of the original code.
If there is any additional code required, please let me know and I'll add it to the question!
Models
Delivery
public class Delivery
{
public int DeliveryID { get; set; }
public int DriverID { get; set; }
public virtual Driver Driver { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
Hospital
public class Hospital
{
public int HospitalID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
Order
public class Order
{
public int OrderID { get; set; }
public int HospitalID { get; set; }
public int? DeliveryID { get; set; }}
public virtual Hospital Hospital { get; set; }
public virtual Delivery Delivery { get; set; }
}
DeliveryVM viewModel
public class DeliveryVM
{
public int? ID { get; set; }
public int DriverID { get; set; }
public SelectList DriverList { get; set; }
public List<OrderVM> Orders { get; set; }
}
Delivery Controller POST method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(DeliveryVM model)
{
// Get the data model based on the ID of the view model
Delivery delivery = db.Deliverys.Find(model.ID);
// Map the view model properties to the data model
delivery.DriverID = model.DriverID;
....
db.SaveChanges();
//Email
Order order = db.Orders.Where(o => o.OrderID == order.DeliveryID).FirstOrDefault(); // I tried this but it didn't work. It was just an attempt
Hospital hospital = db.Hospitals.(h => h.HospitalID == order.HospitalID); // I was going to use this to retrieve the hospitalIDs linked to the Order? Don't know if thats correct
dynamic email = new Email("Example");
email.ID = delivery.DeliveryID;
email.To = hospital.Email; // this is where you set the email you are sending to.
email.Send();
//End
return RedirectToAction("Index");
}
Note
- I removed a lot of code from the Delivery Edit Method for readability, so if necessary I can add that to the question as well.
Source: (StackOverflow)
I'm using Url.Action to generate link in e-mails (with the Postal MVC Framework) that was sent by my application, however, the links generates are showing with "localhost" name, and not domain name.
I'm using the following code:
@Url.Action("AlterarSenha", "Account", null, this.Request.Url.Scheme)
The result is the following:
http://localhost/Account/AlterarSenha
After that, I tried the following code:
@Url.Action("AlterarSenha", "Account", null, this.Request.Url.Scheme, Request.ServerVariables["HTTP_HOST"])
And I got the same result.
How can I get the link with my domain like:
http://www.servicili.com/Account/AlterarSenha
Source: (StackOverflow)
I've currently implemented Postal and I'm using that to send emails on my MVC application. The problem I'm having is that I want to retrieve an email address from my database, instead of hard-coding the address I want to send the email to.
So to give a bit of context on where I'd like to implement this. After I create my Order, I want to send an email address to the Hospital that is linked to that order.
This is what I have tried, but it throws an exception on this line email.To = order.Hospital.Email;
- It does work if I hard code the email address like, for example , email.To = "hospital@hospital.com".
An exception of type 'System.NullReferenceException' occurred in
HealthHabitat.dll but was not handled in user code
I've included it in my Create POST method
so that it triggers once the model has been saved.
The email address is saved as a string in my Hospital Model.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OrderID,HospitalID,StaffID,Date,Time,Expected_Date")] Order order)
{
if (ModelState.IsValid)
{
order.StaffID = 5;
db.Orders.Add(order);
db.SaveChanges();
dynamic email = new Email("Example");
email.To = order.Hospital.Email; // this is where you set the email you are sending to.
email.Send();
Success(string.Format("<i class='fa fa-plus-circle'></i> Please Add your Items!", order.OrderID), true);
return RedirectToAction("Details", new { id = order.OrderID });
}
ViewBag.HospitalID = new SelectList(db.Hospitals, "HospitalID", "Name", order.HospitalID);
Danger("<i class='fa fa-warning'></i> Error!", true);
return View(order);
}
Does any one have a solution to this? I'll greatly appreciate it and thanks in advance!
If any additional information is needed, please let me know and I'll add it to the question.
Hospital Model:
public class Hospital
{
public int HospitalID { get; set; }
public string Name { get; set; }
public string Province { get; set; }
public string Email { get; set; }
public string Phone_Number { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
}
Source: (StackOverflow)
Has anyone successfully used Postal
in an Asp.Net 5
? I tried installing Postal.Mvc5
Nuget
package in an MVC 6
project, and although the project compiled it gave runtime errors, specifically the following:
An unhandled exception occurred while processing the request.
FileNotFoundException: Could not load file or assembly 'System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
System.Web.Mvc.BuildManagerViewEngine..ctor(IViewPageActivator viewPageActivator, IResolver`1 activatorResolver, IDependencyResolver dependencyResolver, VirtualPathProvider pathProvider)
TypeInitializationException: The type initializer for 'System.Web.Mvc.ViewEngines' threw an exception.
System.Web.Mvc.ViewEngines.get_Engines()
If anyone has managed to get Postal
working in MVC 6
, please outline the steps involved in getting it successfully configured, and in particular the Asp.Net 5
equivalent of the following smtp configuration.
<configuration>
...
<system.net>
<mailSettings>
<smtp deliveryMethod="network">
<network host="example.org" port="25" defaultCredentials="true"/>
</smtp>
</mailSettings>
</system.net>
...
</configuration>
Source: (StackOverflow)
I'm trying to configure Postal in class library project. To do this I need to configure custom EmailService. On Postal webpage there's a snippet for doing this:
// Get the path to the directory containing views
var viewsPath = Path.GetFullPath(@"..\..\Views");
var engines = new ViewEngineCollection();
engines.Add(new FileSystemRazorViewEngine(viewsPath));
var service = new EmailService(engines);
(See here: http://aboutcode.net/postal/outside-aspnet.html)
Surprisingly, following error is thrown:
System.ArrayTypeMismatchException occurred HResult=-2146233085
Message=Attempted to access an element as a type incompatible with the
array. Source=mscorlib StackTrace:
at System.Collections.Generic.List`1.Insert(Int32 index, T item) InnerException:
To be precise - it's thrown during adding FileSystemRazorViewEngine
to ViewEngineCollection
. FileSystemRazorViewEngine
derives from IViewEngine
and ViewEngineCollection
derives from Collection<IViewEngine>
.
And here's stacktrace:
mscorlib.dll!System.Collections.Generic.List.Insert(int
index, System.__Canon item) + 0x3e bytes
System.Web.Mvc.dll!System.Web.Mvc.ViewEngineCollection.InsertItem(int
index, System.Web.Mvc.IViewEngine item) + 0x89 bytes
I can't figure out what causes the exception.
Source: (StackOverflow)
I've an application developed in Asp.NET MVC, and I'm using the Framework Postal MVC, that is used to send Views as E-mail.
It was working properly, without problem, however, today, started to show me the following message:
The virtual path '/' maps to another application, which is not allowed.
It happens only when I try to use SendAsync (async method to send e-mail), however, it was working before without problem. Furthermore, if I use Send (sync method to send e-mail) it work.
I didn't change anything on the Properties, code, etc.
The most important thing that I've done that I remember, was to Publish the application, but, in the code or configuration, I didn't change nothing more.
It looks like that is losing the HttpContext when doing Async.
--
The Async method started to work again when I added the following parameter in my Web.config:
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
Source: (StackOverflow)