私が持っていた問題の解決策は少し複雑ですが、IFrame修正プログラムと同様に動作します。その結果、処理を処理するポップアップウィンドウが表示され、ユーザーはサイト全体のナビゲーションを継続できます。
ファイルがサーバー(UploadCSVコントローラ)に送信されると、処理の初期キックオフを処理するJavaScriptのビットとともにSuccessページが返されます。ユーザーが「Begin Processing」をクリックすると、初期状態をロードする(状態更新を取得するインターバル・ループを開始する)新しいウィンドウが開き(ImportProcessing/Index)、「StartProcessing」アクションが呼び出され、処理プロセス。
私が使用している "FileProcessor"クラスは、ImportProcessingコントローラ内の静的なdictionairy変数に格納されています。そのキーに基づいてステータス結果が得られます。 FileProcessorは、操作が完了した後、またはエラーが発生した後、速やかに削除されます。
アップロードコントローラー:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadCSV(HttpPostedFileBase uploadFile)
{
var filePath = string.Empty;
if (uploadFile.ContentLength <= 0)
{
return View();
}
filePath = Path.Combine(Server.MapPath(this.UploadPath), "DeptartmentName",Path.GetFileName(uploadFile.FileName));
if (new FileInfo(filePath).Exists)
{
ViewBag.ErrorMessage =
"The file currently exists on the server. Please rename the file you are trying to upload, delete the file from the server," +
"or contact IT if you are unsure of what to do.";
return View();
}
else
{
uploadFile.SaveAs(filePath);
return RedirectToAction("UploadSuccess", new {fileName = uploadFile.FileName, processType = "sonar"});
}
}
[HttpGet]
public ActionResult UploadSuccess(string fileName, string processType)
{
ViewBag.FileName = fileName;
ViewBag.PType = processType;
return View();
}
アップロード成功HTML:この新しいウィンドウが開かれると
@{
ViewBag.Title = "UploadSuccess";
}
<h2>File was uploaded successfully</h2>
<p>Your file was uploaded to the server and is now ready to be processed. To begin processing this file, click the "Process File" button below.
</p>
<button id="beginProcess" >Process File</button>
<script type="text/javascript">
$(function() {
$("#beginProcess").click(BeginProcess);
function BeginProcess() {
window.open("/SomeController/ImportProcessing/[email protected]&[email protected]", "ProcessStatusWin", "width=400, height=250, status=0, toolbar=0, scrollbars=0, resizable=0");
window.location = "/Department/Import/Index";
}
});
</script>
、ファイル処理が開始されます。更新はカスタムFileProcessingクラスから取得されます。
ImportProcessingコントローラー:
public ActionResult Index(string fileName, string type)
{
ViewBag.File = fileName;
ViewBag.PType = type;
switch (type)
{
case "somematch":
if (!_fileProcessors.ContainsKey(fileName)) _fileProcessors.Add(fileName, new SonarCsvProcessor(Path.Combine(Server.MapPath(this.UploadPath), "DepartmentName", fileName), true));
break;
default:
break;
}
return PartialView();
}
ImportProcessingインデックス:
@{
ViewBag.Title = "File Processing Status";
}
@Scripts.Render("~/Scripts/jquery-1.8.2.js")
<div id="StatusWrapper">
<div id="statusWrap"></div>
</div>
<script type="text/javascript">
$(function() {
$.ajax({
url: "GetStatusPage",
data: { fileName: "@ViewBag.File" },
type: "GET",
success: StartStatusProcess,
error: function() {
$("#statusWrap").html("<h3>Unable to load status checker</h3>");
}
});
function StartStatusProcess(result) {
$("#statusWrap").html(result);
$.ajax({
url: "StartProcessing",
data: { fileName: "@ViewBag.File" },
type: "GET",
success: function (data) {
var messag = 'Processing complete!\n Added ' + data.CurrentRecord + ' of ' + data.TotalRecords + " records in " + data.ElapsedTime + " seconds";
$("#statusWrap #message").html(messag);
$("#statusWrap #progressBar").attr({ value: 100, max: 100 });
setTimeout(function() {
window.close();
}, 5000);
},
error: function (xhr, status) {
alert("Error processing file");
}
});
}
});
</script>
最後にステータスチェッカーのhtml:
@{
ViewBag.Title = "GetStatusPage";
}
<h2>Current Processing Status</h2>
<h5>Processing: @ViewBag.File</h5>
<h5>Updated: <span id="processUpdated"></span></h5>
<span id="message"></span>
<br />
<progress id="progressBar"></progress>
<script type="text/javascript">
$(function() {
var checker = undefined;
GetStatus();
function GetStatus() {
if (checker == undefined) {
checker = setInterval(GetStatus, 3000);
}
$.ajax({
url: "[email protected]",
type: "GET",
success: function (result) {
result = result || {
Available: false,
Status: {
TotalRecords: -1,
CurrentRecord: -1,
ElapsedTime: -1,
Message: "No status data returned"
}
};
if (result.Available == true) {
$("#progressBar").attr({ max: result.Status.TotalRecords, value: result.Status.CurrentRecord });
$("#processUpdated").text(result.Status.Updated);
$("#message").text(result.Status.Message);
} else {
clearInterval(checker);
}
},
error: function() {
$("#statusWrap").html("<h3>Unable to load status checker</h3>");
clearInterval(checker);
}
});
}
});
</script>
の入力をありがとう、私はしばらくの間、これで遊んで、それから出てくるものを参照してください。私がこの答えを受け入れることを確認します。 – TNCodeMonkey
私はこの方法を使用してアプローチする最善の方法を見つけることを試みたが、私が必要としていたものではないことに気づいた。スレッドがスレッドに関係なく、アクションが返されるまでポストが開いたままであるという事実を救済することはできません。私は私の解決策で底に答えを加えました。 – TNCodeMonkey