MVC; “System.Web.HttpException:在控制器'SHP.Controllers.EmployeeController'上找不到公共操作方法'删除'。”

时间:2011-03-03 10:13:10

标签: jquery asp.net-mvc ajax

我想从网格中删除一行。我发现我无法使用[HttpDelete]在我的Controller上装饰我的Delete方法,因为它不是跨浏览器兼容的,请参阅http://forums.asp.net/t/1658625.aspx/1?The+DELETE+Http+works+in+FF+but+not+in+IE

我正在使用此EditorTemplate显示网格;

<tr>
    <td>
        <%-- Ajax Delete --%>
        <% if(Model.LeaveId > 0) { %>
        <%: Html.DeleteEmployeeOtherLeave("/Employee/Delete/" + Model.LeaveId.ToString(), Model)%>
        <%} %>
    </td>
    <td><%: Model.LeaveType %></td>
    <td><%: Model.MorningOnlyFlag %></td>
    <td><%: Model.AfternoonOnlyFlag %></td>
    <td><%: Model.DayAmount %></td>
    <td><%: String.Format("{0:ddd MMM d yyyy}", Model.Date)%></td>
</tr>

我的HTML帮助器调用javascript函数;

function DeleteRow(href) {
    var flag = confirm('Are you sure you wish to delete this item?');
    if (flag == true) {
        $.ajax({
            url: href,
            type: 'POST',
            success: function (result) {
                $('#wholepage').html(result);
            }
        });
    }
    return false;

执行此函数,目的是调用Controller上的Delete方法;

 #region Absence (including sickness)
    [HttpGet]        
    [Authorize(Roles = "Administrator, AdminAccounts, ManagerAccounts")]
    public ActionResult EmployeeAbsence()
    {
        if ((SessionObjects.AbsenceStartDate > DateTime.MinValue) && (SessionObjects.AbsenceEndDate > DateTime.MinValue))
            if (SessionObjects.AbsenceSelectedEmployeeId == 0)
                return View(new AbsenceViewModel()
                {
                    AbsenceStartDate = SessionObjects.AbsenceStartDate,
                    AbsenceEndDate = SessionObjects.AbsenceEndDate
                });
            else
                return View(new AbsenceViewModel(
                    SessionObjects.AbsenceStartDate,
                    SessionObjects.AbsenceEndDate,
                    SessionObjects.AbsenceSelectedEmployeeId
                    ));

        return View();
    }

    [HttpPost]
    public ActionResult EmployeeAbsence(AbsenceViewModel _avm)
    {
        if (ModelState.IsValid)
        {
            SessionObjects.AbsenceStartDate = _avm.AbsenceStartDate;
            SessionObjects.AbsenceEndDate = _avm.AbsenceEndDate;
            if (_avm.SearchTextId > 0)
                SessionObjects.AbsenceSelectedEmployeeId = _avm.SearchTextId;
            return RedirectToAction("EmployeeAbsence");
        }
        return View(_avm);
    }

    [HttpPost]
    public ActionResult Delete(int id)
    {
        EmployeeOtherLeaf.Delete(id);
        return RedirectToAction("EmployeeAbsence");
    }
    #endregion

不会调用Delete方法。

我被问及删除链接在我看来是有效的,因为我在FireFox中设置了一个断点,但是这里是在HtmlHelper方法中定义的。

public static MvcHtmlString DeleteEmployeeOtherLeave(this HtmlHelper html, string url, Leave _leave)
{
    string linkText = "Delete";
    return html.RouteLink(linkText, "Default",
        new { _employeeOtherLeaveId = _leave.LeaveId, action = "Delete" },
        new { onclick = "DeleteRow('" + url + "')" }   
        );
}

1 个答案:

答案 0 :(得分:1)

为什么你这样硬编码网址:

<%: Html.DeleteEmployeeOtherLeave("/Employee/Delete/" + Model.LeaveId.ToString(), Model)%>

在处理网址时始终使用网址助手:

<%: Html.DeleteEmployeeOtherLeave(
    Url.Action("Delete", "Employee", new { id = Model.LeaveId }), 
    Model
)%>

您还指定了多少次这个网址?不是更简单:

public static MvcHtmlString DeleteEmployeeOtherLeave(this HtmlHelper<Leave> html)
{
    var leave = html.ViewData.Model;
    return html.RouteLink(
        "Delete", 
        "Default",
        new { _employeeOtherLeaveId = leave.LeaveId, action = "Delete" },
        new { onclick = "return DeleteRow(this);" }
    );
}

会像这样调用:

<%: Html.DeleteEmployeeOtherLeave() %>

(我可能会添加Link后缀,以使此扩展方法对其实际做的更有意义=&gt;生成删除链接)

然后:

function DeleteRow(a) {
    var flag = confirm('Are you sure you wish to delete this item?');
    if (flag == true) {
        $.ajax({
            url: a.href,
            type: 'POST',
            success: function (result) {
                $('#wholepage').html(result);
            }
        });
    }
    return false;
}

另请注意返回语句:onclick = "return DeleteRow(this);"。如果你没有把它放在你的AJAX调用将永远没有时间执行,你将被简单地重定向到删除操作,当然将抛出404异常,因为无法通过GET请求访问此操作。