Track the progress of the database, saving it in real time. asp.net mvc

I need to show the progress of SQL upload in .net 4.5. The goal is to show the "Live" stream on download. So that the user downloading the information can see that the download is working.

Controller method:

private void ProgressUpload(int? SystemGeneralAnnouncementId) {

                var systemGeneralAnnouncement = (SystemGeneralAnnouncementId == null) ? null : _uow.SystemGeneralAnnouncementRepository.GetById(SystemGeneralAnnouncementId.Value);
                List<Status> status = new List<Status>();

                if (systemGeneralAnnouncement.Statuses.Length > 0)
                {
                    status.AddRange(systemGeneralAnnouncement.Statuses.Split(',').Select(item => (Status)Enum.Parse(typeof(Status), item)));
                }

                var allEmailAddresses = new List<PointOfContact>();
                var EmailAddresses = new List<PointOfContact>();

                //retrieve all Point of contact based upon selected statuses per each loop
                var result = new List<PointOfContact>();
                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<PointOfContact>();

                        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<PointOfContact> 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.

      

Save to database:

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);
            }
        }

      

View what is calling the dispatch method:

@model DODMOU.Model.Entities.SystemGeneralAnnouncement
@{
    ViewBag.Title = "Send Email";
    Layout = "~/Views/Shared/_AdministratorLayout.cshtml";
}
<div class="title">
    <h2>Send Email</h2>
</div>
<hr />
<div class="title">
    <h2>Are you sure you want to Send this Email?</h2>
</div>
<div class="row">
    <div class="col-sm-offset-2 col-sm-9">
        <table class="table table-striped table-hover table-bordered table-responsive">
            <tr>
                <th scope="row" class="col-md-1">@Html.DisplayNameFor(model => model.SendToRecipients) :</th>
                <td class="col-md-8">@Html.DisplayFor(model => model.SendToRecipients)</td>
            </tr>
            <tr>
                <th scope="row">@Html.DisplayNameFor(model => model.Subject) :</th>
                <td>@Html.DisplayFor(model => model.Subject)</td>
            </tr>
            <tr>
                <th scope="row">@Html.DisplayNameFor(model => model.EmailBody) :</th>
                <td class="col-sm-8">@MvcHtmlString.Create(HttpUtility.HtmlDecode(Model.EmailBody))</td>
            </tr>
            <tr>
                <th scope="row">@Html.DisplayNameFor(model => model.Since) :</th>
                <td>@Html.DisplayFor(model => model.Since)</td>
            </tr>
        </table>
    </div>
    <div class="row col-sm-offset-2 col-sm-9 text-right">
        <div class="row col-sm-offset-2 col-sm-9 text-right">
            @using (Html.BeginForm("ConfirmSend", "SystemGeneralAnnouncement", FormMethod.Post))
            {
                @Html.AntiForgeryToken()
                @Html.HiddenFor(model => model.SystemGeneralAnnouncementId)
                <div class="form-actions no-color">
                    <input type="submit" value="Send" class="btn btn-primary" /> |
                    @Html.ActionLink("Back to List", "Index")
                </div>
            }
        </div>

    </div>
</div>

      

View that gets download information:

<div class="col-xs-12" style="text-align: center">
    <p>
        <div class="alert alert-success Loading">
            <h2 class="title">General Announcement is Loading...</h2>
            <br />
        </div>
        The selected general announcements are being uploaded...<br />
        <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div> </div>
        @Html.ActionLink("Return to the System General Announcement page.", "Index", "SystemGeneralAnnouncement")
    </p>
    <div id="success" style="display:none">
        <div class="alert alert-success">
            <h2 class="title">General Announcement Successfully Generated!</h2>
        </div>
        The selected general announcement has been successfully generated and will begin sending to the appropriate recipients within the next few minutes.<br />
        @Html.ActionLink("Return to the System General Announcement page.", "Index", "SystemGeneralAnnouncement")
    </div>
</div>
@section scripts{
    <script>
        $.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;
            },

        });
    </script>
    }

      

The ultimate goal here, as stated above, is to allow the user to see a "live" move on the page when uploading files. The return result will be shown after 100% informs them that the download is complete.

My question is, what am I missing to expose the current values ​​to load? it should come from an event listener but doesn't show any results on load.

+3


source to share


1 answer


I suggest using SignalR to update progress data for the Client. Assuming your data to load is IEnumerable

, you need to catch each update to the database in a foreach loop and update the data to the client using SignalR.



see this link: https://www.codeproject.com/Articles/1124691/SignalR-Progress-Bar-Simple-Example-Sending-Live-D

+1


source







All Articles