【问题标题】:Parameter cannot be NULL. Parameter name: HTTP Context参数不能为 NULL。参数名称:HTTP 上下文
【发布时间】:2015-01-22 09:42:57
【问题描述】:

我们如何在运行后台工作线程时利用 HTTP 上下文?使用 MVC 邮件程序通过后台线程发送电子邮件时出现异常。例外:参数不能为 NULL,HTTP 上下文。

【问题讨论】:

标签: c# asp.net-mvc


【解决方案1】:

当同时使用 async/await 和 HTTPContext 时,始终使用 ConfigureAwait(true) 以允许在原始上下文上继续。例如,见下文。您也可以在等待调用时调用 ConfigureAwait。

var task = new Task(() => book.Bindbook()).ConfigureAwait(true); 

task.Start();

【讨论】:

    【解决方案2】:

    我想你的方法需要一个 HttpContext 但不是通过 WebRequest 执行的。

    HttpContext 不容易模拟,但并非不可能。尝试使用此代码分配 HttpContext 当前

            HttpContext.Current = HttpContextHelper.CreateHttpContext(
                new HttpRequest("SomePage.asmx", "http://localhost/SomePage.asmx", ""),
                new HttpResponse(new StringWriter())
            );
    

    HttpContext helper 是一个基于这篇博文http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx的帮助类

    public class HttpContextHelper
    {
        public static HttpContext CreateHttpContext(HttpRequest httpRequest, HttpResponse httpResponse)
        {
    
            var httpContext = new HttpContext(httpRequest, httpResponse);
    
            var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
                                                    new HttpStaticObjectsCollection(), 10, true,
                                                    HttpCookieMode.AutoDetect,
                                                    SessionStateMode.InProc, false);
    
            httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                        null, CallingConventions.Standard,
                                        new[] { typeof(HttpSessionStateContainer) },
                                        null)
                                .Invoke(new object[] { sessionContainer });
    
            return httpContext;
        }
    
    }
    

    但是(这很重要):您可能做错了。 BackgroundWorker 不打算在 MVC 中使用,而是在 Windows 窗体中使用。请尝试改用 TPL。

    public ActionResult SendMail()
    {
        Task.Factory.StartNew(() => MailSender.SendMail(...));
        return View(...);
    }
    

    或者甚至更好,使用异步:

    [AsyncTimeout(150)]
    [HandleError(ExceptionType = typeof(TimeoutException),
                                        View = "TimeoutError")]
    public async Task<ActionResult> SendMailAsync(CancellationToken cancellationToken )
    {
        ViewBag.SyncOrAsync = "Asynchronous";
        return View("SendMail", await MailSender.SendMailAsync(cancellationToken));
    }
    

    这里解释http://www.asp.net/mvc/overview/performance/using-asynchronous-methods-in-aspnet-mvc-4

    【讨论】:

      猜你喜欢
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多