Прерывистое исключение asp.net mvc: «Не удалось найти метод открытого действия ABC на контроллере XYZ». - PullRequest
89 голосов
/ 17 ноября 2009

Я получаю прерывистое исключение, говорящее, что asp.net mvc не может найти метод действия Вот исключение:

Метод публичного действия «Заполнить» может не может быть найдено на контроллере 'Schoon.Form.Web.Controllers.ChrisController'.

Мне кажется, я правильно настроил маршрутизацию, потому что это приложение работает большую часть времени. Вот метод действия контроллера.

[ActionName("Fill")]
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post), UserIdFilter, DTOFilter]
public ActionResult Fill(int userId, int subscriberId, DisplayMode? mode)
{
     //…
}

Маршрут:

routes.MapRoute(
        "SchoonForm",
        "Form/Fill/{subscriberId}",
        new { controller = "ChrisController", action = "Fill" },
        new { subscriberId = @"\d+" }
    );

А вот и стек:

System.Web.HttpException: общедоступный Метод действия «Заполнить» не может быть найдено на контроллере 'Schoon.Form.Web.Controllers.ChrisController. в System.Web.Mvc.Controller.HandleUnknownAction (String actionName) в C: \ DEV \ ThirdParty \ MvcDev \ SRC \ SystemWebMvc \ Mvc \ Controller.cs: линия 197 в System.Web.Mvc.Controller.ExecuteCore () в C: \ DEV \ ThirdParty \ MvcDev \ SRC \ SystemWebMvc \ Mvc \ Controller.cs: линия 164 в System.Web.Mvc.ControllerBase.Execute (RequestContext requestContext) в C: \ DEV \ ThirdParty \ MvcDev \ SRC \ SystemWebMvc \ Mvc \ ControllerBase.cs: линия 76 в System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext) в C: \ DEV \ ThirdParty \ MvcDev \ SRC \ SystemWebMvc \ Mvc \ ControllerBase.cs: линия 87 в System.Web.Mvc.MvcHandler.ProcessRequest (HttpContextBase httpContext) в C: \ DEV \ ThirdParty \ MvcDev \ SRC \ SystemWebMvc \ Mvc \ MvcHandler.cs: линия 80 в System.Web.Mvc.MvcHandler.ProcessRequest (HttpContext httpContext) в C: \ DEV \ ThirdParty \ MvcDev \ SRC \ SystemWebMvc \ Mvc \ MvcHandler.cs: линия 68 в System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest (HttpContext httpContext) в C: \ DEV \ ThirdParty \ MvcDev \ SRC \ SystemWebMvc \ Mvc \ MvcHandler.cs: линия 104 в System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () в System.Web.HttpApplication.ExecuteStep (IExecutionStep шаг, логическое и завершено синхронно)

Вот пример моих фильтров, они все работают одинаково:

public class UserIdFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        const string Key = "userId";

        if (filterContext.ActionParameters.ContainsKey(Key))
        {
            filterContext.ActionParameters[Key] = // get the user id from session or cookie
        }

        base.OnActionExecuting(filterContext);
    }
}

Спасибо, Chris

Ответы [ 13 ]

60 голосов
/ 05 января 2010

Мы нашли ответ. Мы просмотрели наши веб-журналы. Он показал, что мы получаем некоторые странные http-действия (глаголы / методы), такие как OPTIONS, PROPFIND и HEAD.

Это кажется причиной некоторых исключений из этих тезисов. Это объясняет, почему оно было прерывистым.

Мы воспроизвели проблему с помощью инструмента curl.exe:

curl.exe -X OPTIONS http://localhost/v2.3.1.0/(S(boztz1aquhzurevtjwllzr45))/Form/Fill/273
curl.exe -X PROPFIND http://localhost/v2.3.1.0/(S(boztz1aquhzurevtjwllzr45))/Form/Fill/273
curl.exe -X HEAD http://localhost/v2.3.1.0/(S(boztz1aquhzurevtjwllzr45))/Form/Fill/273

Мы использовали исправление для добавления раздела авторизации в web.config:

<authorization>
  <deny users="*" verbs="OPTIONS, PROPFIND, HEAD"/>
</authorization>
15 голосов
/ 07 апреля 2011

У нас была похожая проблема, но мы обнаружили, что это происходит из-за того, что пользователь отправлял сообщения в контроллер после истечения времени входа в систему. Затем система перенаправляется на экран входа в систему. После входа в систему он перенаправлялся обратно на URL-адрес, на который пользователь пытался публиковать сообщения, но на этот раз он вместо этого выполнял запрос GET и поэтому не находил действие, помеченное атрибутом [HttpPost].

7 голосов
/ 09 июня 2010

У меня такая же проблема в asp.net mvc. эта ошибка - 404 не найдена. Я решаю проблему таким образом - поместите этот код в MyAppControllerBase (MVC)

    protected override void HandleUnknownAction(string actionName)
    {
        this.InvokeHttp404(HttpContext);
    }

    public ActionResult InvokeHttp404(HttpContextBase httpContext)
    {
        IController errorController = ObjectFactory.GetInstance<PagesController>();
        var errorRoute = new RouteData();
        errorRoute.Values.Add("controller", "Pages");
        errorRoute.Values.Add("action", "Http404");
        errorRoute.Values.Add("url", httpContext.Request.Url.OriginalString);
        errorController.Execute(new RequestContext(
             httpContext, errorRoute));

        return new EmptyResult();
    }
6 голосов
/ 29 октября 2010

У нас только что была та же проблема в нашем приложении, и я смог отследить ее до проблемы javascript / jquery. У нас есть ссылки в нашем приложении, определенные с помощью Html.ActionLink (), которые позже переопределяются в POST с помощью jquery.

Сначала мы определили ссылку:

Html.ActionLink("Click Me", "SomeAction", new { id = Model.Id})

Позже мы переопределяем действие по умолчанию с помощью нашей функции SomePostEventHandler:

 $(document).ready(function() {
      $('#MyLink').click(SomePostEventHandler);
 }

Это было ударом по нашему действию MVC с фильтром HttpPost:

 [HttpPost]
 public ActionResult SomeAction(int id)
 {
      //Stuff
 }

То, что мы обнаружили, это то, что большую часть времени это прекрасно работало. Однако при некоторых медленных загрузках страницы (или действительно быстрых пользователях) пользователь щелкал ссылку до того, как сработало событие jquery $ (document) .ready (), что означало, что он пытался вместо GET / Controller / SomeAction / XX вместо размещение.

Мы не хотим, чтобы пользователь ПОЛУЧИЛ этот URL, поэтому удаление фильтра для нас не вариант. Вместо этого мы просто напрямую связали событие onclick ссылки действия (нам пришлось немного изменить SomePostEventHandler (), чтобы это работало):

string clickEvent = "return SomePostEventHandler(this);";

Html.ActionLink("Click Me", "SomeAction", new { id = Model.Id}, new { onclick = clickEvent })

Итак, мораль этой истории, по крайней мере для нас, заключается в том, что, если вы видите эти ошибки, отследите URL-адрес, который, по вашему мнению, вы размещаете, и убедитесь, что это так.

2 голосов
/ 19 сентября 2011

У меня тоже была эта проблема.

В моем случае это было связано с глагольными ограничениями запрошенного действия, где представление было POST, но частичное представление запрашивалось только в поддерживаемых GET и HEAD. Добавление глагола POST к AcceptVerbsAttribute (в MVC 1.0) решило проблему.

1 голос
/ 25 июля 2015

В настоящее время принятый ответ работает должным образом, но не является основным вариантом использования этой функции. Вместо этого используйте функцию, определенную в ASP.NET. В моем случае я отрицал все, кроме GET и POST:

  <system.webServer>
  <security>
      <requestFiltering>
          <verbs allowUnlisted="false">
              <add verb="GET" allowed="true"/>
              <add verb="POST" allowed="true"/>
          </verbs>
      </requestFiltering>
  </security>
 </system.webServer>

С приведенным выше фрагментом кода MVC правильно вернет 404

1 голос
/ 12 января 2015

Удалите атрибуты [HttpGet], и это будет работать:)

1 голос
/ 27 сентября 2013

Из журналов IIS наша проблема была вызвана попыткой робота Google POST и GET для действия контроллера только POST.

Для этого случая я рекомендую обращаться с 404, как предложение Дмитрия.

1 голос
/ 30 мая 2011

У меня похожая проблема с qq Загрузка файла

Когда действие публикации /Document/Save Я получаю исключение Метод открытого действия 'Сохранить' не найден в контроллере 'Project.Controllers.DocumentController'.

Но если действие публикации /Document/Save/, сообщение корректно и работает!

Боже, храни / ?

0 голосов
/ 25 апреля 2019

Посмотрите, достаточно ли простого просмотра нужного URL, чтобы воспроизвести ошибку. Это было бы, если действие было определено только как действие POST. Это позволяет воспроизвести ошибку по желанию.

В любом случае вы можете глобально обработать ошибку, как показано ниже. Другой ответ здесь, который ссылается на HandleUnknownAction, обрабатывает только URL с плохими именами действий, а не плохими именами контроллеров. Следующий подход обрабатывает оба.

Добавьте это к вашему базовому контроллеру (код просмотра здесь опущен):

public ActionResult Error(string errorMessage)
{
    return View("Error");  // or do something like log the error, etc.
}

Добавьте глобальный обработчик исключений в Global.asax.cs, который вызывает описанный выше метод или делает все остальное, что вы хотите сделать с перехваченной ошибкой 404:

void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();  // get the exception object
    HttpException httpException = ex as HttpException;

    if (httpException != null && httpException.GetHttpCode() == 404)  // if action not found
    {
        string errorMessage = "The requested page was not found.";

        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Base");
        routeData.Values.Add("action", "Error");
        routeData.Values.Add("errorMessage", errorMessage);

        Server.ClearError();
        Response.TrySkipIisCustomErrors = true;

        // Go to our custom error view.
        IController errorController = new BaseController();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...