我想在我的asp.net应用程序中访问HttpContext.Current
Task.Factory.Start(() =>{
//HttpContext.Current is null here
});
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个错误?
我有以下mvc动作.
public async Task<JsonResult> DoSomeLongRunningOperation()
{
return await Task.Run(() =>
{
//Do a lot of long running stuff
//The underlying framework uses the HttpContext.Current.User.Identity.Name so the user is passed on the messagebus.
}
}
Run Code Online (Sandbox Code Playgroud)
在任务中,HttpContext变为null.我们做了很多尝试,但没有任何事情让我们确信HttpContext总是在我们的新线程中可用.
有没有在异步任务中使用HttpContext的解决方案?
在我们的IocContainer中,我们注册了以下对象,该对象将用户名传递给框架.
public class HttpContextUserIdentityName : ICredentials
{
public string Name
{
get { return HttpContext.Current.User.Identity.Name; }
}
}
Run Code Online (Sandbox Code Playgroud)
在持久化到数据库之前,在很多地方调用此代码.
我们需要另一种方法来获取用户的用户名启动webrequest或修复HttpContext为null的问题.
因为持久化到数据库发生在任务中,所以在进入任务之前无法访问HttpContext.
我也想不出一个临时持久保存用户名的安全方法,所以我可以实现另一个ICredentials服务对象.
为了澄清我的问题,我一直在开发一个应用程序,它根据用户的输入(使用excel电子表格)执行大量数据库更新/ Web服务调用.如果有很多更新,则该过程可能需要超过20分钟才能运行.
为了阻止我的用户界面冻结/超时,我一直在研究多线程,这样我就可以以异步方式运行我的长时间运行过程,同时只需在进程运行时显示动画gif.
这一切似乎与我的测试数据一起很好地运行,但是当我在实际的长时间运行过程中替换时,我得到关于HttpContext.Current.User.Identity.Name的错误.我对这个念起来从这个第一条我把它意味着,如果你在页面指令设置的"异步"属性设置为"真"和所使用的方法RegisterAsyncTask你可以再访问HttpContext.Current.然而,对我来说,这似乎并非如此.我敢肯定,这件事情我做的,所以这里是我的代码(我主要是使用下面的文章来写这个了第二条和第三条):
ASP.NET页面
<%@ Page Title="Home Page" Async="true" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.cs" Inherits="MyApp.Index" %>
Run Code Online (Sandbox Code Playgroud)
C# - RegisterAsyncTask是在单击按钮时完成的,它启动长时间运行的进程:
protected void ProcessUpdates()
{
//Register async task to allow the processing of valid updates to occurr in the background
PageAsyncTask task = new PageAsyncTask(OnBegin, OnEnd, OnTimeOut, null);
RegisterAsyncTask(task);
}
IAsyncResult OnBegin(Object sender, EventArgs e, AsyncCallback cb, object state)
{
return Worker.BeginWork(cb, state);
}
private void OnEnd(IAsyncResult asyncResult)
{
//UpdateResults list should now have been filled …Run Code Online (Sandbox Code Playgroud) 这种方法 - doDayBegin(item.BranchId)需要很长时间才能执行.所以我用Parallel.ForEach它来并行执行它.当我使用正常foreach循环时它的工作正常但当我使用Parallel.ForEach它时显示此错误
对象引用未设置为对象的实例.
public ActionResult Edit([DataSourceRequest] DataSourceRequest request)
{
try
{
JavaScriptSerializer js = new JavaScriptSerializer();
List<DB0010020Vm> _listDB0010020Vm = new List<DB0010020Vm>();
string dataDB0010020vm = Request.Form["griddetailsvm"];
if (!string.IsNullOrEmpty(dataDB0010020vm))
{
_listDB0010020Vm = js.Deserialize<List<DB0010020Vm>>(dataDB0010020vm).
Where(d => d.IsValid == "YES").ToList();
}
DateTime start = DateTime.UtcNow;
Parallel.ForEach(_listDB0010020Vm, item =>
{
doDayBegin(item.BranchId);
});
DateTime end = DateTime.UtcNow;
TimeSpan duration = end - start;
return Json(new
{
success = true,
message = "Day Begin Process Completed Successfully!" + duration …Run Code Online (Sandbox Code Playgroud) 我有一个FakeHttpContext我一直在尝试修改以包含一些标题用于测试目的
public static HttpContext FakeHttpContext()
{
var httpRequest = new HttpRequest("", "http://stackoverflow/", "");
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
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;
}
Run Code Online (Sandbox Code Playgroud)
此作品,未经头,但是当我添加任何的代码行中之间的HttpRequest和StringWriter的线.
httpRequest.Headers.Add("blah", "1234");
httpRequest.Headers["blah"] = "1234";
Run Code Online (Sandbox Code Playgroud)
它抛出
System.Web.dll中发生了'System.PlatformNotSupportedException'类型的异常,但未在用户代码中处理
我创建了一个名为MyLongRunningClass包含方法的类:
public string ProcessLongRunningAction(IEnumerable<HttpPostedFileBase> files ,string id)
{
int currentIndex = 0;
foreach (HttpPostedFileBase file in files)
{
currentIndex++;
lock(syncRoot)
{
string path=HttpContext.Current.Server.MapPath("~//Content//images //"+file.FileName);//Excecption is created here........
file.SaveAs(path);
}
Thread.Sleep(300);
}
return id;
}
Run Code Online (Sandbox Code Playgroud)
从控制器调用此方法,使用文件列表保存在images目录中.无论何时HttpContext.Current.Server.MapPath("~//Content//images//"+file.FileName)被执行NullReferenceException抛出,HttpContext.Current总是如此null.当我使用session时会发生同样的事情.我不知道代码有什么问题.
我有一个异步方法,它使用 HttpContext.Current,它由另一个在后台运行的代码使用,例如
var result = Task.Run(async () => await SomeMethod()).Result;
Run Code Online (Sandbox Code Playgroud)
HttpContext.Current 始终为 null。有没有办法将 HttpContext 传递给后台任务?
c# ×6
asp.net ×3
asp.net-mvc ×3
httpcontext ×3
async-await ×2
.net ×1
asp.net-4.0 ×1
asynchronous ×1
c#-4.0 ×1
linq ×1
unit-testing ×1