I have encountered a very strange problem. Basically, there is a Delete ActionLink
. Once clicked, the code checks the condition, checks true/false, stays on current page or goes to Delete view
.
I have posted the solution for this scenario and got some very helpful replies. I worked on it and took it to a situation where I was about to succeed.
Anyway, here are the codes
Index View: AJAX calls the Delete action
, returns JSON or EmptyResult. If EmptyResult, then it is a failure as the original ActionLink has been disabled, AJAX will call the error
function, which calls another action "Delete2"
.
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.CustomerId }, htmlAttributes: new { @class = "mergo-actionlink" }) |
@Html.ActionLink("Details", "Details", new { id = item.CustomerId }, htmlAttributes: new { @class = "mergo-actionlink" }) |
@Html.ActionLink("Delete", "Delete", new { id = item.CustomerId }, htmlAttributes: new { @class = "mergo-actionlink-delete", data_value = item.CustomerId })
</td>
</tr>
}
</table>
<script type="text/javascript">
$('.mergo-actionlink-delete').click(
function () {
var clickedId = $(this).attr('data-value');
$.ajax({
dataType: "json",
url: '@Url.Action("Delete", "Customers")',
data: { id: clickedId},
success: function (data) {
alert(data.message);
},
error: function () {
alert("EmptyResult returns.");
debugger;
$.post('@Url.Action("Delete2", "Customers")', { id: clickedId });
},
async: false
});
return false;
});
</script>
Controllers:
public ActionResult Delete(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
if (customer.Orders.ToList().Count() != 0)
{
return Json(new { message = "This customer has order(s) attached." }, "text/plain", JsonRequestBehavior.AllowGet);
}
return new EmptyResult();
}
public ActionResult Delete2(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
Delete2.cshtml
@model MergoMVC.Customer
@{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Customer</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.UserName)
</dt>
<dd>
@Html.DisplayFor(model => model.UserName)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Password)
</dt>
<dd>
@Html.DisplayFor(model => model.Password)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Email)
</dt>
<dd>
@Html.DisplayFor(model => model.Email)
</dd>
</dl>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-default" /> |
@Html.ActionLink("Back to List", "Index")
</div>
}
</div>
And I do have Delete.cshtml
and Delete2.cshtml
views for the actions. The symptom is - from debugging, Visual Studio went into Delete2
action, returned the "customer" to Delete2.cshtml
view, executed it from head to toe. But the browser stayed still on index page. I think something is wrong with the return false;
in the AJAX. I'm new to this, so I need some help. Thanks.