Reputation: 10193
Can anyone see why this code doesn't work? I know that someone will notice that I am using Delete links and I should be using a DELETE verb rather than a POST, but I have not been able to resolve that issue, even with the help of SO. No the issue here is that I click on delete, the underlying data gets deleted OK, but after I delete the data, when I try to redirect to the Payroll GET method, it does not get called and as a result the screen does not get refreshed. So here is the code on the Controller;
[HttpGet]
[Authorize(Roles = "Administrator, AdminAccounts, ManagerAccounts")]
public ActionResult Payroll()
{
if ((SessionObjects.PeriodStartDate > DateTime.MinValue) && (SessionObjects.PeriodEndDate > DateTime.MinValue))
if (SessionObjects.PayrollSelectedEmployeeId == 0)
return View(new PayrollViewModel()
{
PeriodStartDate = SessionObjects.PeriodStartDate,
PeriodEndDate = SessionObjects.PeriodEndDate
});
else
return View(new PayrollViewModel(
SessionObjects.PeriodStartDate,
SessionObjects.PeriodEndDate,
SessionObjects.PayrollSelectedEmployeeId
));
return View();
}
[HttpPost]
[Authorize(Roles = "Administrator, AdminAccounts, ManagerAccounts")]
public ActionResult Payroll(PayrollViewModel _pvm)
{
if (ModelState.IsValid)
{
SessionObjects.PeriodStartDate = _pvm.PeriodStartDate;
SessionObjects.PeriodEndDate = _pvm.PeriodEndDate;
if (_pvm.SearchTextId > 0)
SessionObjects.PayrollSelectedEmployeeId = _pvm.SearchTextId;
return RedirectToAction("Payroll");
}
return View(_pvm);
}
//[AcceptVerbs(HttpVerbs.Delete)]
[HttpPost]
[Authorize(Roles = "Administrator, AdminAccounts, ManagerAccounts")]
public RedirectToRouteResult Delete(int id)
{
EmployeeOtherLeaf.Delete(id);
return RedirectToAction("Payroll");
}
Part of the View and Editor Template;
<table class="groupBorder">
<tr>
<th></th>
<th>Leave Type</th>
<th>Notes</th>
<th>Day Amount</th>
<th>Date</th>
<th>Approver</th>
</tr>
<%: Html.EditorFor(x => x.LeaveList)%>
</table>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SHP.WebUI.Models.Leave>" %>
<%@ Import Namespace="SHP.WebUI.HtmlHelpers" %>
<%@ Import Namespace="SHP.Models" %>
<%: Html.RowStyle(Model.RowColour) %>
<tr>
<td style="background-color:White;">
<%-- Ajax Delete --%>
<% if(Model.LeaveId > 0) { %>
<%: Html.DeleteEmployeeOtherLeave()%>
<%} %>
</td>
<td><%: Model.LeaveType %></td>
<td><%: Model.Notes %></td>
<td><%: Model.DayAmount %></td>
<td><%: String.Format("{0:ddd MMM d yyyy}", Model.Date)%></td>
<td><%: Model.ApproverName %></td>
</tr>
</tbody> <%-- Leave this here, it closes from the above Html.RowStyle!--%>
HTML Helper method;
public static MvcHtmlString DeleteEmployeeOtherLeave(this HtmlHelper<Leave> html)
{
var leave = html.ViewData.Model;
return html.RouteLink(
"Delete",
"Default",
new {id = leave.LeaveId, action = "Delete" },
new { onclick = "return DeleteRow(this);" }
);
}
Upvotes: 0
Views: 2655
Reputation: 1038830
You seem to be invoking the Delete action using AJAX inside the DeleteRow
javascript function (which you haven't shown). You cannot redirect in AJAX requests. That's the whole point them: do not refresh the entire browser but only portions of it.
If you wanted to perform a full redirect inside the success callback of your AJAX call you could use the window.location.href
property, like this:
success: function(result) {
window.location.href = '/somecontroller/Payroll';
}
Now of course doing something like this is meaningless. I would simply use a standard HTML form which will post top the Delete action and not use any javascript at all:
<% if(Model.LeaveId > 0) { %>
<% using (Html.BeginForm("Delete", "Home", new { id = leave.LeaveId })) { %>
<button type="submit">Delete</button>
<% } %>
<% } %>
Now when the form is submitted the Delete action will be invoked which will perform the actual delete and redirect the browser to the Payroll action => pretty standard HTTP dialogue.
And if you decide to go this way you even get a bonus: you could decorate your controller action with the [HttpDelete]
attribute and use a technique on the client :
<% if(Model.LeaveId > 0) { %>
<% using (Html.BeginForm("Delete", "Home", new { id = leave.LeaveId })) { %>
<%= Html.HttpMethodOverride(HttpVerbs.Delete) %>
<button type="submit">Delete</button>
<% } %>
<% } %>
and then:
[HttpDelete]
[Authorize(Roles = "Administrator, AdminAccounts, ManagerAccounts")]
public RedirectToRouteResult Delete(int id)
{
EmployeeOtherLeaf.Delete(id);
return RedirectToAction("Payroll");
}
Under the hood it's not a real DELETE HTTP verb since browsers do not support it for forms but it simulates it using a hidden field which ASP.NET MVC understands and is capable to properly redispatch the request to the corresponding action.
Upvotes: 1