参数不能为NULL。参数名称:HTTP上下文

时间:2015-01-22 09:42:58

标签: c# asp.net-mvc

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

2 个答案:

答案 0 :(得分:1)

我想你的方法需要一个HttpContext但是没有用WebRequest执行。

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

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

HttpContext帮助程序是基于此博客文章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(...);
}

甚至更好,使用async:

[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

答案 1 :(得分:1)

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

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

task.Start();