值不能为空。参数名称:httpContext

Posted

技术标签:

【中文标题】值不能为空。参数名称:httpContext【英文标题】:Value cannot be null. Parameter name: httpContext 【发布时间】:2016-01-16 15:21:09 【问题描述】:

我在尝试使用 Postal.mvc5 发送电子邮件时遇到此错误消息“”。

尝试调用 Postal.EmailService.CreateMailMessage(Email email) 时发生此错误。

有人可以帮忙吗?谢谢。

以下是错误详情。

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 触发器通过电子邮件助手发送电子邮件:

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);
    

电子邮件助手类: 在 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);
            
        );
    

【问题讨论】:

我们需要看一些源代码。 添加了一些源代码。 它可能与Task.Factory.StartNew(() =>(例如另一个线程)有关,因为新线程中的上下文始终为空。尝试传递上下文以使其工作,首先,您可以通过在 SendEmail 函数的开头和结尾注释掉线程工厂来尝试查看是否是该问题。 【参考方案1】:

我在尝试使用 SmtpClient 发送电子邮件时遇到了一些问题。在大多数情况下,除非您拥有自己的电子邮件服务器(例如,仅在生产中工作),否则您无法使其工作,因为仅允许在主机/服务器上发送以防止垃圾邮件。上下文异常可能与上述问题有关。我认为您应该尝试类似的方法(简化):

public static bool Email(string subject, string fromEmail, string toEmail, string fromName, string toName)

   bool result = false;
   bool useDefaultCredentials = true;

   var credentials = new NetworkCredential
   
      UserName = CacheHelper.Settings.SmtpUserName,
      Password = CacheHelper.Settings.SmtpPassword
   ;

   if (!string.IsNullOrEmpty(CacheHelper.Settings.SmtpUserName) && !string.IsNullOrEmpty(CacheHelper.Settings.SmtpPassword))
   
      useDefaultCredentials = false;
   

   SmtpClient smtp = new SmtpClient()
   
      Host = CacheHelper.Settings.SmtpHost,
      Port = CacheHelper.Settings.SmtpPort.HasValue ? CacheHelper.Settings.SmtpPort.Value : 25,
      EnableSsl = CacheHelper.Settings.SmtpSSL,
      DeliveryMethod = SmtpDeliveryMethod.Network,
      UseDefaultCredentials = useDefaultCredentials,
      Credentials = useDefaultCredentials ? CredentialCache.DefaultNetworkCredentials : credentials,
      Timeout = 10000
   ;

   MailAddress from = new MailAddress(fromEmail, fromName);
   MailAddress to = new MailAddress(toEmail, toName);
   string body = PreMailer.Net.PreMailer.MoveCssInline(message.Body).Html;

   using (MailMessage message = new MailMessage(from, to)  Subject = subject, IsBodyHtml = true, Body = body )
   
      smtp.Send(message); //you might need to use try catch here (it can blow up)
      result = true;
   
   smtp.Dispose();

   return result;

【讨论】:

嗨 Gillsoft AB。谢谢回复。目前的解决方法是使用您建议的方法。

以上是关于值不能为空。参数名称:httpContext的主要内容,如果未能解决你的问题,请参考以下文章

值不能为空。参数名称:编码器[重复]

值不能为空。参数名称:httpContext

值不能为空。参数名称:starter中的connectionString appsettings.json

值不能为空。参数名称:dest

使用 DAL2 访问数据:值不能为空。参数名称:con

值不能为空。参数名称:routeCollection + ApiController