92 votes

Exception intermittente asp.net mvc : "Une méthode d'action publique ABC n'a pas pu être trouvée sur le contrôleur XYZ."

Je reçois une exception intermittente disant que asp.net mvc ne peut pas trouver la méthode d'action. Voici l'exception :

Une méthode d'action publique "Fill" pourrait ne pas être trouvée sur le contrôleur Schoon.Form.Web.Controllers.ChrisController'.

Je pense avoir configuré le routage correctement car cette application fonctionne la plupart du temps. Voici la méthode d'action du contrôleur.

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

L'itinéraire :

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

Et voici la pile :

System.Web.HttpException : Une action publique d'action publique 'Fill' n'a pas pu être trouvé sur le contrôleur Schoon.Form.Web.Controllers.ChrisController'. à l'adresse System.Web.Mvc.Controller.HandleUnknownAction(String actionName) dans C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\Controller.cs :ligne 197 à System.Web.Mvc.Controller.ExecuteCore() dans C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\Controller.cs :ligne 164 à System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) dans C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\ControllerBase.cs :ligne 76 à System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) dans C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\ControllerBase.cs :ligne 87 à System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) dans C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs :ligne 80 chez System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) dans C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs :ligne 68 à System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) dans C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs :ligne 104 à System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() à l'adresse System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Voici un exemple de mes filtres ; ils fonctionnent tous de la même manière :

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

Merci, Chris

28 votes

J'ai eu un problème similaire qui, je pense, mérite d'être signalé ici car c'est le premier résultat qui est apparu dans Google lors de la recherche de l'exception ci-dessus. Mon application a généré cette exception lors de la soumission d'un formulaire invalide. Cela était dû au fait que la page qui était (re)rendue appelait RenderAction et que l'action qui était appelée pour rendre une vue partielle était marquée avec l'attribut HttpGet, la suppression de cet attribut a résolu le problème.

3 votes

J'ai également remarqué ce comportement - peut-être est-il préférable de ne pas appliquer d'attributs Http aux méthodes du contrôleur qui renvoient des PartialViewResults.

1 votes

@s1mm0t : a raison. Pour mon cas, son commentaire a résolu le problème.

62voto

Chris Schoon Points 560

Nous avons trouvé la réponse. Nous avons regardé dans nos journaux web. Ils montrent que nous recevons des actions http étranges (verbes/méthodes) comme OPTIONS, PROPFIND et HEAD.

Cela semble être la cause de certaines de ces exceptions. Cela explique pourquoi c'était intermittent.

Nous avons reproduit le problème avec l'outil 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

La solution que nous avons utilisée a été d'ajouter une section d'autorisation à web.config :

<authorization>
  <deny users="*" verbs="OPTIONS, PROPFIND, HEAD"/>
</authorization>

4 votes

Nous avons également constaté que les robots vont parfois parcourir votre site - et même le javascript - pour trouver des liens. Ils essaient ensuite d'envoyer des requêtes à ces URI avec le mauvais verbe HTTP. Par exemple, si vous avez un appel jQuery à une action -- par exemple /some-action et que cette méthode nécessite un POST, le robot peut tenter d'envoyer un GET, ce qui provoquera l'affichage de cette erreur. Vos journaux Web pourraient certainement aider à confirmer si c'est le cas. Nous avons même vu Googlebot faire cela.

0 votes

Je rencontre cette même erreur uniquement sur le serveur Live (IIS 7.5). Le déploiement fonctionne bien sur ma machine de développement ainsi que sur une autre machine de support. L'ajout de ces verbes et la suppression de HttpGet n'ont pas résolu le problème. Veuillez me faire part de toute autre suggestion.

0 votes

Au lieu de refuser les demandes HEAD entrantes, vous pouvez signifier une réponse appropriée. Voir stackoverflow.com/a/3197128/12484

15voto

Johann Strydom Points 977

Nous avons rencontré un problème similaire, mais nous avons découvert que cela se produisait parce qu'un utilisateur publiait des messages dans un contrôleur après que sa connexion ait expiré. Le système redirigeait alors vers l'écran de connexion. Après la connexion, il redirigeait vers l'URL à laquelle l'utilisateur essayait de poster, mais cette fois-ci, il effectuait une requête GET à la place et ne trouvait donc pas l'action qui était marquée avec un attribut [HttpPost].

0 votes

Ma solution actuelle consiste, dans la mesure du possible, à toujours effectuer une redirection vers l'action Index à la fin d'une action. Désolé pour cette réponse tardive.

7voto

Dmitriy Points 178

J'ai le même problème dans asp.net mvc. Cette erreur - 404 not found. J'ai résolu le problème de la manière suivante - j'ai mis ce code dans le fichier 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();
    }

6voto

jslatts Points 2937

Nous venons d'avoir le même problème sur notre application et j'ai pu remonter à un problème de javascript/jquery. Nous avons des liens dans notre application définis à l'aide de Html.ActionLink() qui sont ensuite remplacés par des POST par jquery.

Nous avions d'abord défini le lien :

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

Plus tard, nous remplacerons l'action par défaut par notre fonction SomePostEventHandler :

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

Cela frappait notre action MVC qui avait un filtre HttpPost :

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

Ce que nous avons constaté, c'est que la plupart du temps, cela fonctionnait très bien. Cependant, sur certains chargements de pages lents (ou sur des utilisateurs vraiment rapides), l'utilisateur cliquait sur le lien avant que l'événement jquery $(document).ready() ne se déclenche, ce qui signifie qu'il essayait d'obtenir GET /Controller/SomeAction/XX au lieu d'afficher.

Nous ne voulons pas que l'utilisateur obtienne cette URL, donc la suppression du filtre n'est pas une option pour nous. À la place, nous câblons directement l'événement onclick du lien d'action (nous avons dû modifier légèrement SomePostEventHandler() pour que cela fonctionne) :

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

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

La morale de l'histoire, du moins pour nous, est que si vous rencontrez ces erreurs, recherchez l'URL vers laquelle vous PENSEZ POSTER et assurez-vous que c'est bien le cas.

0 votes

En général, vous devez être prudent lorsque vous POST à partir d'un lien hypertexte html. Les hyperliens existent pour amener l'utilisateur à une autre page (http get) et les boutons html doivent soumettre un formulaire (http post).

2voto

WolfyUK Points 348

J'ai aussi eu ce problème.

Dans mon cas, c'était lié à des restrictions verbales sur l'action demandée, où la vue était une POST mais la vue partielle demandée dans le cadre du support GET y HEAD seulement. L'ajout de la POST verbe au AcceptVerbsAttribute (dans MVC 1.0) a résolu le problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X