2009-11-16 29 views
81

Recibo una excepción intermitente diciendo que asp.net mvc no puede encontrar el método de acción. Aquí está la excepción:Excepción intermitente de asp.net mvc: "No se encontró un método de acción pública ABC en el controlador XYZ".

Un método de acción pública 'llenar' podría no se encuentran en el controlador 'Schoon.Form.Web.Controllers.ChrisController'.

Creo que tengo el enrutamiento configurado correctamente porque esta aplicación funciona la mayor parte del tiempo. Aquí está el método de acción del controlador.

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

La ruta:

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

Y aquí está la pila:

System.Web.HttpException: Un método público acción 'llenar' no pudo ser encontrado en el controlador 'Schoon.Form.Web.Controllers.ChrisController'. en System.Web.Mvc.Controller.HandleUnknownAction (String actionName) en C: \ dev \ Terceros \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: línea 197 en System.Web.Mvc.Controller .ExecuteCore() en C: \ dev \ Terceros \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: línea 164 en System.Web.Mvc.ControllerBase.Execute (RequestContext RequestContext) en C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs: línea 76 en System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext) en C: \ dev \ Terceros \ MvcDev \ src \ SystemWebMvc \ \ MVC ControllerBase.cs: Línea 87 al System.Web.Mvc.MvcHandler.ProcessRequest (HttpContextBase HttpContext) en C: \ dev \ Terceros \ MvcDev \ src \ SystemWebMvc \ Mvc \ MvcHandler.cs: línea 80 en System.Web.Mvc.MvcHandler.ProcessRequest (HttpContext HttpContext) en C: \ dev \ Terceros \ MvcDev \ src \ SystemWebMvc \ Mvc \ MvcHandler.cs: línea 68 en System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest (HttpContext HttpContext) en C: \ dev \ Terceros \ MvcDev \ src \ SystemWebMvc \ Mvc \ MvcHandler.cs: línea 104 en System.Web.H ttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() en System.Web.HttpApplication.ExecuteStep (IExecutionStep paso, Boole & completedSynchronously)

Este es un ejemplo de mis filtros todos funcionan de la misma manera:

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

Gracias, Chris

+25

que tenía un problema similar que creo que vale la pena señalar aquí que este fue el primer resultado que surgió en Google cuando se busca la excepción anteriormente. Mi aplicación arrojó esta excepción al enviar un formulario no válido. Esto se debió a que la página que se estaba reescribiendo llamaba a RenderAction y la acción que se llamó para generar una vista parcial se marcó con el atributo HttpGet, eliminando que este atributo resolviera el problema. – s1mm0t

+3

También he notado este comportamiento: quizás sea mejor no aplicar ningún atributo Http a los métodos del controlador que devuelven PartialViewResults. – Stuart

+3

@ s1mm0t - Me salvó la cordura. – LiamB

Respuesta

55

Encontramos la respuesta. Revisamos nuestros registros web. Demostró que recibíamos algunas acciones http (verbos/métodos) raros como OPTIONS, PROPFIND y HEAD.

Esto parece ser la causa de algunas de estas excepciones. Esto explica por qué fue intermitente.

Hemos reproducido el problema con la herramienta 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 solución se utilizó fue la de añadir una sección de autorización para web.config:

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

También hemos encontrado que los bots algunas veces rastrea su sitio, e incluso javascript, para encontrar enlaces. Luego intenta enviar solicitudes a estos URI con el verbo HTTP incorrecto. Por ejemplo, si tiene una llamada jQuery a alguna acción, por ejemplo,/some-action y esto método requiere un POST, el bot puede intentar enviar un GET, lo que hará que se muestre este error. Sus registros web definitivamente podrían ayudar a confirmar si este fuera el caso. Incluso vemos que googlebot hace esto. – jakejgordon

+0

Tengo este mismo error solo en el servidor Live (IIS 7.5). La implementación funciona bien en mi máquina de desarrollo, así como en otra máquina de soporte. agregar estos verbos y eliminar HttpGet no solucionó el problema. Cualquier sugerencia adicional por favor. – bjan

+0

Una alternativa a la denegación de solicitudes HEAD entrantes, es posible que desee enviar una respuesta adecuada. Ver https://stackoverflow.com/a/3197128/12484 –

0

¿No debería ser

routes.MapRoute(
     "SchoonForm", 
     "Form/Fill/{subscriberId}", 
     new { controller = "Chris", action = "Fill" }, 

Además, ¿qué hace su f ilters hacer? ¿No pueden ocultar la acción, como ActionMethodSelectorAttribute?

+0

Eso es un error de edición. Estaba tratando de proteger a los inocentes. –

+0

Ellos pueblan algunos de los parámetros. Por ejemplo, UserIdFilter es un ayudante para obtener el ID de usuario de la sesión/cookie/etc. Rellena el primer parámetro. Editaré la publicación para incluirlo. –

7

Me'v obtuvo el mismo problema en asp.net mvc. este error - 404 no encontrado. Me resolver el problema de esta manera - poner este código en 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

simplemente tuvimos el mismo problema en nuestra aplicación y que era capaz de rastrear a un problema de Javascript/jQuery. Tenemos enlaces en nuestra aplicación definidos usando Html.ActionLink() que luego serán reemplazados en POST por jquery.

En primer lugar, había definido el enlace:

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

Más tarde nos anulan la acción por defecto con nuestra función SomePostEventHandler:

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

Esto estaba golpeando nuestra acción MVC que tenía un filtro HttpPost:

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

Lo que encontramos es que la mayoría de las veces esto funcionó muy bien. Sin embargo, en algunas cargas de página lentas (o usuarios realmente rápidos), el usuario hacía clic en el enlace antes de que el evento jquery $ (document) .ready() se activara, lo que significa que intentaban OBTENER/Controlador/SomeAction/XX en lugar de destino.

No queremos que el usuario OBTENGA esa url, por lo que eliminar el filtro no es una opción para nosotros. En su lugar, simplemente cableado el evento onclick del enlace de acción directa (tuvimos que cambiar SomePostEventHandler() ligeramente para que esto funcione):

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

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

Así, moraleja de la historia, al menos para nosotros, es que si se están viendo estos errores, rastrea la URL en la que PIENSAS que estás PUBLICANDO y asegúrate de que estás.

13

Tuvimos un problema similar, pero descubrimos que estaba sucediendo porque un usuario estaba publicando en un controlador después de que se había agotado el tiempo de espera.El sistema luego se redirige a la pantalla de inicio de sesión. Después de iniciar sesión, redirigió a la URL que el usuario intentaba publicar, pero esta vez estaba haciendo una solicitud GET y, por lo tanto, no encontró la acción marcada con un atributo [HttpPost].

+1

Tengo este mismo problema. ¿Qué hiciste para resolverlo? –

+0

Mi solución actual es, en la medida de lo posible, hacer siempre un redireccionamiento a la acción de índice al final de una acción. Lo siento por la respuesta tardía. –

1

que tienen el problema similar con qq File Upload

Cuando la acción posterior es /Document/Save consigo la excepción No se encontró un método de acción pública 'Guardar' en el controlador 'Project.Controllers.DocumentController'.

Pero si la acción posterior es /Document/Save/, la publicación es correcta y funciona.

Dios guarde el /?

+0

slash te refieres! :) –

2

Yo también tuve este problema.

En mi caso estaba relacionado al verbo restricciones a la acción solicitada, donde la vista era un POST pero la vista parcial de ser solicitada dentro apoyado GET y HEAD solamente. Agregar el verbo POST al AcceptVerbsAttribute (en MVC 1.0) resolvió el problema.

0

Mi causa principal fue similar a la que se menciona en el comentario.

Estaba ajaxSubmitting un formulario con el clic de un botón. Uno de los campos del formulario era del tipo Date. Sin embargo, debido a la diferencia en los formatos de fecha entre el cliente y la máquina servidor, no ejecutó el método POST en el controlador. El servidor devolvió una respuesta 302 y luego envió una solicitud GET para el mismo método nuevamente.

Sin embargo, la acción en el controlador estaba decorada con el atributo HttpPost y, por lo tanto, no pudo encontrar el método y envió una respuesta 404.

Acabo de arreglar el código de modo que la falta de coincidencia en los formatos de Fecha no causara un error y se solucionó el problema.

1

De los registros de IIS, nuestro problema fue causado por el robot de Google que intentó el POST y un GET por una acción de controlador solo de POST.

Para este caso, recomiendo manejar la 404 como sugerencia de Dmitriy.

0

Retire los atributos [HttpGet] y funcionará :)

0

La respuesta aceptada actualmente funciona como se esperaba, pero no es el caso de uso primario para la función. En su lugar, use la característica definida por ASP.NET. En mi caso, lo negó todo, pero GET y POST:

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

Con el código anterior, MVC devolverá correctamente un 404

0

Para cualquier persona que tenga este problema con AngularJS, MVC y {{imagepath}} escriba insertos en los atributos src de la imagen, por ejemplo:

"Un método de acción público '{{}} imagepath previous.png' no se encontró en el controlador"

La solución es utilizar ng-src en lugar de src.

Esperamos que esto ayude a alguien :)

+0

casi un año después, estaba buscando esto :) tnx! – Verthosa

Cuestiones relacionadas