MVC;«System.Web.HttpException: метод открытого действия« Удалить »не найден в контроллере« SHP.Controllers.EmployeeController ».» - PullRequest
0 голосов
/ 03 марта 2011

Я хочу удалить строку из моей сетки. Я обнаружил, что не могу украсить свой метод Delete на моем контроллере с помощью [HttpDelete], потому что он не совместим с разными браузерами, см. http://forums.asp.net/t/1658625.aspx/1?The+DELETE+Http+works+in+FF+but+not+in+IE

Я отображаю сетку, используя этот шаблон Editor;

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

Эта функция выполняется, и намерение состоит в том, чтобы вызвать метод 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 Ответ

1 голос
/ 03 марта 2011

Почему вы жестко кодируете URL-адреса, например:

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

Всегда используйте помощники URL при работе с URL-адресами:

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

Кроме того, сколько раз вы указываете этот URL-адрес?Разве это не было бы проще:

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, чтобы сделать этот метод расширения немногоболее важно то, что он делает на самом деле => создать ссылку для удаления)

, а затем:

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

Также обратите внимание на выражение return здесь: onclick = "return DeleteRow(this);".Если вы этого не сделаете, у вашего вызова AJAX никогда не будет времени для выполнения, и вы просто будете перенаправлены на действие Delete, которое, конечно, вызовет исключение 404, потому что это действие не доступно через запрос GET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...