以下是情景 -
我有一个表单,通过Ajax POST将文件上传到Action。文件上传后,将对其进行处理,并将数据插入数据库。这可能需要一些时间,所以我希望能够将消息发送回用户,让用户知道文件所处的过程中的哪一步。基本上我现在所拥有的是:
[HttpPost]
public void UploadAndProcessFile()
{
Session["UserMessage"] = "Start";
// Do some stuff
Session["UserMessage"] = "25% done";
// Do some stuff
Session["UserMessage"] = "50% done";
// Do some stuff
Session["UserMessage"] = "75% done";
// Do some stuff
Session["UserMessage"] = "Completed!";
}
[HttpGet]
putlic JsonResults GetFileProcessStatus()
{
string returnMessage = (Session["UserMessage"] ?? "");
return Json(returnMessage, JsonRequestBehavior.AllowGet);
}
在客户端,我通过ajax将表单发布到UploadAndProcessFile Action,然后有一个函数不断向GetFileProcessStatus发出ajax get请求。问题是,当我执行ajax get getqeust到GetFileProcessStatus时,Session [“UserMessage”]始终为null。我也尝试过TempData而不是Session,结果相同。根据我对Session的理解,我在这里想要完成的是不可行的,因为Session的优先级是给第一个调用者的。在我的情况下,第一个调用者是UploadAndProcessFile。我希望这是有道理的,有人可以提供帮助!
谢谢 - JD
答案 0 :(得分:2)
class ParameterForMyProcess
{
public string criteria { get; set; }
public Guid processID { get; set; }
public HttpContext context { get; set; }
}
private Guid StartProcess(string criteria)
{
// we will use this id later to get status updates on this specific process.
var processID = Guid.NewGuid();
// the thread we are starting can only take one parameter,
// so we create a container for all the data we might want to use
// and pass that in as the single parameter into the process.
var parameter = new ParameterForMyProcess()
{
criteria = criteria,
processID = processID,
context = System.Web.HttpContext.Current
};
var thread = new System.Threading.Thread(
new System.Threading.ParameterizedThreadStart(CreateProcess));
thread.Start(parameter);
return processID;
}
private void CreateProcess(object parameter)
{
// cast the object to our parameter type
var myParameter = parameter as ParameterForMyProcess;
// you now have access to some data if you wish
var criteria = myParameter.criteria;
// process ID to report progress with
var processID = myParameter.processID;
System.Web.HttpContext.Current = myParameter.context;
// Do something
updateStatus(processID, "Hello World");
}
private void updateStatus(Guid processID, string status)
{
// store the status in the http cache.
var key = "CreateProcess:" + processID.ToString();
var cache = System.Web.HttpContext.Current.Cache;
var oldStatus = cache[key];
var newStatus = oldStatus + "<br/>" + status;
cache[key] = newStatus;
// this implementation relies on the browser to trigger an action which will clean up this data from the cache.
// there is no guarantee this will be triggered (user closes browser, etc),
// but since the cache has means for eventually removing this data, this isn't a big risk.
}
public JsonResult GetProcessStatus(string processID)
{
var status = System.Web.HttpContext.Current.Cache["CreateProcess:" + processID.ToString()];
return Json(new { status = status });
}