会话无法通过对控制器的多个Ajax调用保留TempData

时间:2018-08-25 20:05:03

标签: ajax asp.net-mvc

我正在尝试通过几种Action方法使用对象(VideoInfo)。表单将带有视频文件的视图模型发送到VideoController中的Upload方法。它将上传视频并返回生成的GUID。返回回调后,将对Convert方法进行新的ajax调用,该方法返回guid。如Create.cshtml的javascript部分所示,它还进行了另外两个Ajax调用,一个调用Progress方法,另一个调用Azure方法。

当尝试在Azure方法和Progress方法中获取VideoInfo对象时,videoInfo为null。虽然它成功保留了Upload方法和Convert方法之间的数据。我正在使用TempData.Peek(),因此不应将其标记为删除。

我可以看到Upload和Convert方法使用的是VideoController的相同实例,而Progress和Azure方法使用的是另一个实例,我想这可能与问题有关。

InstanceId when running Upload method: 23ef96fa-c746-4722-ad07-e9e40fc95f29
InstanceId when running Convert method: 23ef96fa-c746-4722-ad07-e9e40fc95f29
InstanceId when running Progress method: 0aba24b2-ccb8-434d-a27d-cc66cb52c466
InstanceId when running Azure method: 0aba24b2-ccb8-434d-a27d-cc66cb52c466

如何在VideoController中的Ajax调用之间保留数据?
为什么前两个调用的实例ID相同,但是随后又改变了?

VideoController.cs

using System;

namespace MediaPortal.Controllers
{
    [Authorize(Roles = "Admin")]
    public class VideoController : Controller
    {
        private static Guid InstanceId { get; }

        static VideoController()
        {
            InstanceId = Guid.NewGuid();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Upload(CreateVideoViewModel model)
        {
            if (ModelState.IsValid)
            {
                if (model.File != null)
                {
                    Debug.WriteLine("Upload method InstanceId: " + InstanceId.ToString());

                    // ...

                    TempData[videoInfo.Id] = videoInfo;

                    videoInfo.cvvm.File.SaveAs(videoInfo.TempPath);

                    return Json(new { Successfull = true, Id = videoInfo.Id });
                }

                return null;
            }

            return null;
        }

        [HttpPost]
        public ActionResult Convert(string id)
        {
            Debug.WriteLine("Convert method InstanceId: " + InstanceId.ToString());

            // Create new object of FFMpegConvertor
            var converter = new FFMpegConverter();
            VideoInfo videoInfo = (VideoInfo)TempData.Peek(id);

            // ...

            return Json(new { Successfull = true, Id = videoInfo.Id });
        }

        [HttpPost]
        public ActionResult Azure(string id)
        {
            Debug.WriteLine("Azure method InstanceId: " + InstanceId.ToString());

            VideoInfo videoInfo = (VideoInfo)TempData[id];

            // ...

            if (videoUpload != null && thumbnailUpload != null)
            {
                Video video = new Video
                {
                    Id = videoInfo.Id.ToString(),
                    Name = videoInfo.cvvm.Name,
                    ProjectId = videoInfo.cvvm.ProjectId,
                    Type = "mp4",
                    VideoUri = videoUpload.Uri.ToString(),
                    ThumbnailUri = thumbnailUpload.Uri.ToString()
                };

                db.Videos.Add(video);
                db.SaveChanges();

                return Json(new { Successful = true, Data = Url.Action("Index", new { projectId = videoInfo.cvvm.ProjectId }) });
            }

            return null;
        }

        [HttpPost]
        public JsonResult Progress(string id)
        {
            Debug.WriteLine("Progress method InstanceId: " + InstanceId.ToString());

            try
            {
                VideoInfo videoInfo = (VideoInfo)TempData.Peek(id);

                return Json(new { Data = videoInfo.Progress });
            }
            catch
            {
                return Json(new { Data = "No Video Information in Dictionary for Id: " + id });
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
} 

Create.cshtml(JQuery / Ajax)

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>

<script>
    $.noConflict();
    jQuery(document).ready(function ($) {

        var bar = $('.progress-bar');
        var percent = $('.percent');

        $('#Myform').ajaxForm({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            beforeSend: function () {
                var percentVal = '0%';
                bar.width(percentVal);
                percent.html(percentVal);
            },
            uploadProgress: function (event, position, total, percentComplete) {
                var percentVal = percentComplete + '%';
                bar.width(percentVal);
                percent.html(percentVal);
            },
            complete: function (uploadStatus) {
                console.log("Upload finished for video with Id: " + JSON.parse(uploadStatus.responseText).Id);
                setTimeout(function () { progress(uploadStatus) }, 1000);
                $.ajax({
                    type: "POST",
                    url: '@Url.Action("Convert", "Video")?id=' + JSON.parse(uploadStatus.responseText).Id,
                    dataType: "json",
                    contentType: "application/json; charset=utf-8",
                    complete: function (convertStatus) {
                        console.log("Conversion finished for video with Id: " + JSON.parse(convertStatus.responseText).Id);
                        $.ajax({
                            type: "POST",
                            url: '@Url.Action("Azure", "Video")?id=' + JSON.parse(convertStatus.responseText).Id,
                            dataType: "json",
                            contentType: "application/json; charset=utf-8",
                            complete: function (azureStatus) {
                                window.location.href = JSON.parse(azureStatus.responseText).Data;
                            }
                        });
                    }
                });
            }
        });

        function progress(uploadStatus) {
            $.ajax({
                type: "POST",
                url: '@Url.Action("Progress", "Video")?id=' + JSON.parse(uploadStatus.responseText).Id,
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                complete: function (progressStatus) {
                    console.log("Progress: " + JSON.parse(progressStatus.responseText).Data);
                    if (JSON.parse(progressStatus.responseText).Data < 100) {
                        setTimeout(function () { progress(uploadStatus) }, 1000);
                    }
                    else if (JSON.parse(progressStatus.responseText).Data >= 100) {
                        console.log("Video Conversion Completed");
                    }
                    else {
                        console.log("Something went wrong");
                    }
                }
            })
        }
    });
</script> 

1 个答案:

答案 0 :(得分:0)

似乎IIS Express是问题所在。我不能说为什么。我意识到了这一点,因为当我将项目部署到Azure中的生产服务器时,一切正常。

因此,我没有使用IIS Express,而是在开发计算机上安装了IIS,此后它可以完美运行。