跟踪数据库的进度保存在“live”进度条asp.net mvc中

我需要在.net 4.5中显示SQL加载的进度。 目标是显示上传发生的“实时”流程。 这样上传信息的人就可以看到上传工作正常。

控制器方法:

private void ProgressUpload(int? SystemGeneralAnnouncementId) { var systemGeneralAnnouncement = (SystemGeneralAnnouncementId == null) ? null : _uow.SystemGeneralAnnouncementRepository.GetById(SystemGeneralAnnouncementId.Value); List status = new List(); if (systemGeneralAnnouncement.Statuses.Length > 0) { status.AddRange(systemGeneralAnnouncement.Statuses.Split(',').Select(item => (Status)Enum.Parse(typeof(Status), item))); } var allEmailAddresses = new List(); var EmailAddresses = new List(); //retrieve all Point of contact based upon selected statuses per each loop var result = new List(); foreach (var item in status) { result = _uow.PointOfContactRepository.GetAllByStatus(item).ToList(); allEmailAddresses.AddRange(result); } // Retrieve the email addresses based on the who is intended to receive the email message if (systemGeneralAnnouncement.SendToRecipients.Contains("(1) All Three Contacts")) { EmailAddresses = allEmailAddresses; } else { if (systemGeneralAnnouncement.SendToRecipients.Contains("(2) All first Contacts")) { pocEmailAddresses.AddRange(allEmailAddresses.Where(r => r.PointOfContactType == PointOfContactTypes.Primary).ToList()); } if (systemGeneralAnnouncement.SendToRecipients.Contains("(3) All Second Contacts")) { pocEmailAddresses.AddRange(allEmailAddresses.Where(r => r.PointOfContactType == PointOfContactTypes.Secondary).ToList()); } if (systemGeneralAnnouncement.SendToRecipients.Contains("(4) All third contacts")) { pocEmailAddresses.AddRange(allEmailAddresses.Where(r => r.PointOfContactType == PointOfContactTypes.SigningAuthority).ToList()); } if (systemGeneralAnnouncement.SendToRecipients.Contains("(5) All fourth Contacts")) { pocEmailAddresses.AddRange(allEmailAddresses.Where(r => r.PointOfContactType == PointOfContactTypes.TuitionRates).ToList()); } if (systemGeneralAnnouncement.SendToRecipients.Contains("(6) Specified Email Address")) { var pocs = new List(); string[] emails = systemGeneralAnnouncement.EmailAddresses.Split(','); foreach (string email in emails) { var addPoc = new PointOfContact { Email = email }; User user = _uow.UserRepository.GetByEmail(email); if (user == null) { add.FirstName = "Not Created Account Yet"; } else { addPoc.FirstName = user.FirstName; addPoc.LastName = user.LastName; } List idAssociatedToUser = _uow.PointOfContactRepository .GetAllPocsByEmail(email) .ToList(); if (idAssociatedToUser.Count == 0) { addPoc.IDNumber = "N/A"; } else { string[] idArray = idAssociatedToUser .Select(x => x.IDNumber) .ToArray(); addPoc.IDNumber = string.Join(",", opeidArray); } pocs.Add(addPoc); } EmailAddresses.AddRange(pocs); } } // if any poc addresses were found... if (EmailAddresses.Count > 0) { string emailBody = WebUtility.HtmlDecode(systemGeneralAnnouncement.EmailBody); foreach (PointOfContact emailAddress in EmailAddresses.Where(x => x.Email != "" && x.Email != null).ToList()) { string firstName = emailAddress.FirstName == null ? "" : emailAddress.FirstName.Trim(); string lastName = emailAddress.LastName == null ? "" : emailAddress.LastName.Trim(); string userName = firstName + " " + lastName; //Below I Used SqlCommand vs EF because EF has AutoDetectChangesEnabled and it slows things down when adding to the context. Instead of tuning it by turning it to false or //configure it to use AddRange, SqlCommand is the best option for speed. 

保存到数据库:

 SaveToDatabase(emailAddress.Email, emailBody, systemGeneralAnnouncement.Subject, UserIdentityHelper.GetUserEmailAddress + " (" + UserIdentityHelper.GetUserId + ")", systemGeneralAnnouncement.SystemGeneralAnnouncementId, userName, emailAddress.IDNumber); LogInstitutionEmail(systemGeneralAnnouncement.Subject, emailBody, emailAddress.Email, emailAddress.IDNumber, systemGeneralAnnouncement.EmailAttachmentLocation); } } } private void LogInstitutionEmail(string subject, string emailBody, string email, string opeidNumber, string emailAttachment) { try { using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MasterContext"].ConnectionString)) { conn.Open(); SqlCommand cmd; if (string.IsNullOrEmpty(emailAttachment)) { cmd = new SqlCommand("Insert Into Emails (Since, Subject, Email, EmailAddress, OpeidNumber, FirstReadDateTime) VALUES(@Since, @Subject, @Email, @EmailAddress, @OpeidNumber, NULL)", conn); } else { cmd = new SqlCommand("Insert Into Emails (Since, Subject, Email, EmailAddress, OpeidNumber, FirstReadDateTime, Attachment) VALUES(@Since, @Subject, @Email, @EmailAddress, @IDNumber, NULL, @Attachment)", conn); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@Attachment", Value = emailAttachment }); } cmd.Parameters.Add(new SqlParameter() { ParameterName = "@Since", Value = DateTime.Now }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@Subject", Value = subject }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@Email", Value = emailBody }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@EmailAddress", Value = email }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@idNumber", Value = idNumber }); cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); conn.Close(); } } catch (Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); } } private void SaveToDatabase(string emailRecipient, string emailBody, string subject, string userWhoSentIt, int systemGeneralAnnouncementId, string userName, string opeidNumber) { try { using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MasterContext"].ConnectionString)) { conn.Open(); var cmd = new SqlCommand("Insert Into EmailQueue (EmailRecipients, EmailBody, EmailSubject, UserWhoSentIt, QueueDate, SystemGeneralAnnouncementId, UserName, OpeidNumber) VALUES(@EmailRecipients, @EmailBody, @EmailSubject, @UserWhoSentIt, @QueueDate, @SystemGeneralAnnouncementId, @UserName, @OpeidNumber)", conn); cmd.CommandType = CommandType.Text; cmd.Parameters.Add(new SqlParameter() {ParameterName = "@EmailRecipients", Value = emailRecipient }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@EmailBody", Value = emailBody }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@EmailSubject", Value = subject }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@UserWhoSentIt", Value = userWhoSentIt }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@QueueDate", Value = DateTime.Now }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@SystemGeneralAnnouncementId", Value = systemGeneralAnnouncementId }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@UserName", Value = userName }); cmd.Parameters.Add(new SqlParameter() { ParameterName = "@idNumber", Value = idNumber }); cmd.ExecuteNonQuery(); conn.Close(); } } catch (Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); } } 

查看调用Post方法:

 @model DODMOU.Model.Entities.SystemGeneralAnnouncement @{ ViewBag.Title = "Send Email"; Layout = "~/Views/Shared/_AdministratorLayout.cshtml"; } 

Send Email


Are you sure you want to Send this Email?

@Html.DisplayNameFor(model => model.SendToRecipients) : @Html.DisplayFor(model => model.SendToRecipients)
@Html.DisplayNameFor(model => model.Subject) : @Html.DisplayFor(model => model.Subject)
@Html.DisplayNameFor(model => model.EmailBody) : @MvcHtmlString.Create(HttpUtility.HtmlDecode(Model.EmailBody))
@Html.DisplayNameFor(model => model.Since) : @Html.DisplayFor(model => model.Since)
@using (Html.BeginForm("ConfirmSend", "SystemGeneralAnnouncement", FormMethod.Post)) { @Html.AntiForgeryToken() @Html.HiddenFor(model => model.SystemGeneralAnnouncementId)
| @Html.ActionLink("Back to List", "Index")
}

接收上传信息的视图:

 

General Announcement is Loading...


The selected general announcements are being uploaded...
@Html.ActionLink("Return to the System General Announcement page.", "Index", "SystemGeneralAnnouncement")

General Announcement Successfully Generated!

The selected general announcement has been successfully generated and will begin sending to the appropriate recipients within the next few minutes.
@Html.ActionLink("Return to the System General Announcement page.", "Index", "SystemGeneralAnnouncement")
@section scripts{ $.ajax({ type: 'POST', url: "ProgressUpload, systemGeneralAnnouncement", data: {}, success: function (data) { $(".Loading").hide(); $("#success").css("display","block"); }, xhr: function () { var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function (evt) { if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; } }, false); return xhr; }, }); }

如上所述,此处的最终目标是允许用户在上载文件时查看页面上的“实时”进度。 成功返回将在100%之后显示,让他们知道上传完成。

我的问题是,我缺少什么来公开当前值上传? 它应该来自事件监听器,但不会显示任何上传进度。

我建议使用SignalR将进度数据更新到客户端。 假设您的上传数据是IEnumerable类型,您需要在foreach循环中捕获每次更新到DB并使用SignalR将数据更新到客户端。

看到这个链接: https : //www.codeproject.com/Articles/1124691/SignalR-Progress-Bar-Simple-Example-Sending-Live-D