Conor8630
Conor8630

Reputation: 345

ASP.NET MVC Call action in order?

I have two actions. One creates a record in my table and saves changes to the database and then an action that sends that record in an email.

I think the problem is that the actions are being preformed at the same time so the email action can't grab the data required as it hasn't been created yet so it's grabbing the previous record.

I am using an onclick for the two actions so it's the same button.

View:

div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-warning" onclick="SendEmail()" />
            </div>
        </div>
    </div>
}

var SendEmail = function () {

    $.ajax({
        type: "Post",
        url: "/HolidayRequestForms/SendMailToManager",
        success: function (data) {

            alert("Success");


        }


    })

}

Controller Actions:

Create:

 public ActionResult Create()
    {
        ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName");
        return View();
    }

    // POST: HolidayRequestForms/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "RequestID,EmployeeID,StartDate,FinishDate,HoursTaken,Comments,YearCreated,MonthCreated,DayCreated,YearOfHoliday,Approved")] HolidayRequestForm holidayRequestForm)
    {
        if (ModelState.IsValid)
        {
            db.HolidayRequestForms.Add(holidayRequestForm);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName", holidayRequestForm.EmployeeID);
        return View(holidayRequestForm);
    }

Emails:

public JsonResult SendMailToManager()
    {
        string name = Session["Name"].ToString();

        var AreaManagerEmailCatch = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.AreaManagerEmail);
        var ManagerEmailCatch = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.ManagerEmail);
        var StartDateCatch = db.HolidayRequestForms.Where(s => s.Employee.Email.Equals(name)).Select(s => s.StartDate);


        var des = (from a in db.Employees
                   where a.Email == name
                   select a.AreaManagerEmail);

        var ManEmail = (from b in db.Employees
                   where b.Email == name
                   select b.ManagerEmail);

        var SD = (from c in db.HolidayRequestForms.OrderByDescending(c => c.RequestID)
                        where (c.Employee.Email == name) && (c.Employee.EmployeeID == c.EmployeeID)
                        select c.StartDate);

        DateTime StartDate = SD.FirstOrDefault();
        string ManagerEmail = ManEmail.FirstOrDefault();
        string AreaManagerEmail = des.FirstOrDefault();



        bool result = false;

        result = SendEmail(AreaManagerEmail, "LotusWorks Holiday Request", "Hi there " + AreaManagerEmail + ",<br><br>[EmployeeEmail] has requested a holiday<br><br>The Employee will not be available to work From: <b>" + StartDate + "</b> to <b>[FinishDate]</b>.<br><br>Please forward this email to " + ManagerEmail + " with a response of Accept or Reject<br><br><br>Kind Regards,<br><br>LotusWorks Holiday Tracker");

        return Json(result, JsonRequestBehavior.AllowGet);

Is there a way that I can use the create action first, then the email action so the desired record will be sent in the email.

Upvotes: 0

Views: 40

Answers (2)

Charles Owen
Charles Owen

Reputation: 2840

I wouldn't have an action that sends an email. Instead I would make the Email method just a regular method in a business class and invoke it if the record is created.

if (ModelState.IsValid)
{
        db.HolidayRequestForms.Add(holidayRequestForm);
        int changes = db.SaveChanges();
        if(changes > 0){SendEmail();}
        return RedirectToAction("Index");
}

Upvotes: 0

TanvirArjel
TanvirArjel

Reputation: 32069

Is there a way that I can use the create action first, then the email action so the desired record will be sent in the email.

Surely has! You can simply do as follows:

First remove the onclick="SendEmail()" the from the submit button as it is needed anymore:

<input type="submit" value="Create" class="btn btn-warning"/>

Then in the Create POST method in controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "RequestID,EmployeeID,StartDate,FinishDate,HoursTaken,Comments,YearCreated,MonthCreated,DayCreated,YearOfHoliday,Approved")] HolidayRequestForm holidayRequestForm)
{
    if (ModelState.IsValid)
    {
        db.HolidayRequestForms.Add(holidayRequestForm);
        db.SaveChanges();
        SendMailToManager(); // Call the SendMailToManager() method here. It will only be called if `holidayRequestForm` created successfully.
        return RedirectToAction("Index");
    }

    ViewBag.EmployeeID = new SelectList(db.Employees, "EmployeeID", "FullName", holidayRequestForm.EmployeeID);
    return View(holidayRequestForm);
}

Now update the SendMailToManager() as follows:

private void SendMailToManager()
{
    string name = Session["Name"].ToString();

    var AreaManagerEmailCatch = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.AreaManagerEmail);
    var ManagerEmailCatch = db.Employees.Where(s => s.Email.Equals(name)).Select(s => s.ManagerEmail);
    var StartDateCatch = db.HolidayRequestForms.Where(s => s.Employee.Email.Equals(name)).Select(s => s.StartDate);


    var des = (from a in db.Employees
               where a.Email == name
               select a.AreaManagerEmail);

    var ManEmail = (from b in db.Employees
               where b.Email == name
               select b.ManagerEmail);

    var SD = (from c in db.HolidayRequestForms.OrderByDescending(c => c.RequestID)
                    where (c.Employee.Email == name) && (c.Employee.EmployeeID == c.EmployeeID)
                    select c.StartDate);

    DateTime StartDate = SD.FirstOrDefault();
    string ManagerEmail = ManEmail.FirstOrDefault();
    string AreaManagerEmail = des.FirstOrDefault();

    SendEmail(AreaManagerEmail, "LotusWorks Holiday Request", "Hi there " + AreaManagerEmail + ",<br><br>[EmployeeEmail] has requested a holiday<br><br>The Employee will not be available to work From: <b>" + StartDate + "</b> to <b>[FinishDate]</b>.<br><br>Please forward this email to " + ManagerEmail + " with a response of Accept or Reject<br><br><br>Kind Regards,<br><br>LotusWorks Holiday Tracker");

 }

Upvotes: 1

Related Questions