0

My MVC Mailer instance is failing when I send from the server. I'm getting the error Value cannot be null.Parameter name: httpContext when I attempt to send an email.

my code looks like this:

    public static void SendApproval(TimeOffRequest request)
    {
        MailService mailer = new MailService();
        mailer.ViewData.Model = request;

        MvcMailMessage mailMessage = new MvcMailMessage
        {
            Subject = $"PTO request approved for {request.StartTime} to {request.EndTime}",
            From = new MailAddress("calendar@company.com"),
        };
        mailMessage.To.Add(new MailAddress(request.Requester.Email));

        if (mailMessage.To.Count == 0)
            return;

        mailer.PopulateBody(mailMessage, "RequestApproved");
        mailMessage.Send();
    }

It's specifically failing on the line mailer.PopulateBody(mailMessage, "RequestApproved");

It is being called from the post of a controller endpoint. Why is the context missing in this scenario? I attempted to manually pass the context and that failed as well.

Heres the top of the stack trace:

System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase httpContext) +505
   Mvc.Mailer.MailerBase.CreateControllerContext() +98
   Mvc.Mailer.MailerBase.ViewExists(String viewName, String masterName) +127

1 Answers1

0

MVCMailer's PopulateBody method has 3 arguments and 4 arguments overload in MailerBase class (3 arguments version actually calls 4 arguments overload with masterName set as null):

// 3 arguments overload
public virtual void PopulateBody(MailMessage mailMessage, string viewName, Dictionary<string, string> linkedResources) 
{
    PopulateBody(mailMessage, viewName, null, linkedResources);
}

// 4 arguments overload
public virtual void PopulateBody(MailMessage mailMessage, string viewName, string masterName = null, Dictionary<string, string> linkedResources = null) 
{
    ...
}

Based from that findings, use additional null to fill unnecessary method arguments, either using 3 or 4 arguments version:

// 3 arguments
mailer.PopulateBody(mailMessage, "RequestApproved", null); 

// 4 arguments
mailer.PopulateBody(mailMessage, "RequestApproved", null, null);

Since the possible cause originated from MailerBase class (in var routeData = RouteTable.Routes.GetRouteData(CurrentHttpContext); where CurrentHttpContext passed null value), you can see utilization of null-checking for HttpContextBase virtual property in this request.

Similar issue:

MvcMailer unit tests: System.ArgumentNullException httpContext cannot be null

Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61