asp.net-mvc 间歇性 asp.net mvc 异常:“在控制器 XYZ 上找不到公共操作方法 ABC。”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1745182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:56:54  来源:igfitidea点击:

Intermittent asp.net mvc exception: “A public action method ABC could not be found on controller XYZ.”

asp.net-mvcexception

提问by Chris Schoon

I'm getting an intermittent exception saying that asp.net mvc can't find the action method. Here's the exception:

我收到一个间歇性异常,说 asp.net mvc 找不到操作方法。这是例外:

A public action method 'Fill' could not be found on controller 'Schoon.Form.Web.Controllers.ChrisController'.

在控制器“Schoon.Form.Web.Controllers.ChrisController”上找不到公共操作方法“Fill”。

I think I have the routing set up correctly because this application works most of the time. Here is the controller's action method.

我想我的路由设置正确,因为这个应用程序大部分时间都在工作。这是控制器的操作方法。

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

The route:

路线:

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

And here is the stack:

这是堆栈:

System.Web.HttpException: A public action method 'Fill' could not be found on controller 'Schoon.Form.Web.Controllers.ChrisController'. at System.Web.Mvc.Controller.HandleUnknownAction(String actionName) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\Controller.cs:line 197 at System.Web.Mvc.Controller.ExecuteCore() in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\Controller.cs:line 164 at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\ControllerBase.cs:line 76 at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\ControllerBase.cs:line 87 at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs:line 80 at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs:line 68 at System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs:line 104 at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

System.Web.HttpException:在控制器“Schoon.Form.Web.Controllers.ChrisController”上找不到公共操作方法“Fill”。在 System.Web.Mvc.Controller.HandleUnknownAction(String actionName) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\Controller.cs:line 197 at System.Web.Mvc.Controller.ExecuteCore() in C :\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\Controller.cs:line 164 at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\ ControllerBase.cs:line 76 at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) in C:\dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\ControllerBase.cs:line 87在 C 中的 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) 中:

Here is an example of my filters they all work the same way:

这是我的过滤器的示例,它们的工作方式相同:

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

Thanks, Chris

谢谢,克里斯

采纳答案by Chris Schoon

We found the answer. We looked into our web logs. It showed that we were receiving some weird http actions (verbs/methods) like OPTIONS, PROPFIND and HEAD.

我们找到了答案。我们查看了我们的网络日志。它表明我们收到了一些奇怪的 http 操作(动词/方法),如 OPTIONS、PROPFIND 和 HEAD。

This seems to the cause of some of theses exceptions. This explains why it was intermittent.

这似乎是导致其中一些例外的原因。这就解释了为什么它是间歇性的。

We reproduced the issue with the curl.exe tool:

我们使用 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

The fix we used was to add an authorization section to web.config:

我们使用的修复是在 web.config 中添加一个授权部分:

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

回答by Johann Strydom

We had a similar issue, but found that it was happening because a user was posting to a controller after his login had timed out. The system then redirected to the login screen. After logging in it redirected back to the URL the user was trying to post to, but this time it was doing a GET request instead and therefore not finding the action which was marked with an [HttpPost] attribute.

我们遇到了类似的问题,但发现这是因为用户在登录超时后向控制器发帖。然后系统重定向到登录屏幕。登录后,它重定向回用户试图发布的 URL,但这次它执行的是 GET 请求,因此没有找到用 [HttpPost] 属性标记的操作。

回答by Dmitriy

I'v got the same problem in asp.net mvc. this error - 404 not found. I resolve problem this way - put this code in MyAppControllerBase(MVC)

我在 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();
    }

回答by jslatts

We just had the same issue on our application and I was able to trace it to a javascript/jquery issue. We have links in our application defined using Html.ActionLink() that are later overridden into POSTs by jquery.

我们刚刚在我们的应用程序上遇到了同样的问题,我能够将其追溯到 javascript/jquery 问题。我们的应用程序中有使用 Html.ActionLink() 定义的链接,这些链接稍后会被 jquery 覆盖到 POST 中。

First we had defined the link:

首先我们定义了链接:

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

Later we override the default action with our SomePostEventHandler function:

稍后我们使用 SomePostEventHandler 函数覆盖默认操作:

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

This was hitting our MVC action that had a HttpPost filter:

这是我们的 MVC 操作,它有一个 HttpPost 过滤器:

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

What we found is that most of the time this worked great. However, on some slow page loads (or really fast users), the user was clicking the link before the jquery $(document).ready() event was firing, meaning that they were trying to GET /Controller/SomeAction/XX instead of posting.

我们发现大部分时间这都很好用。然而,在一些缓慢的页面加载(或非常快的用户)上,用户在 jquery $(document).ready() 事件触发之前点击链接,这意味着他们试图 GET /Controller/SomeAction/XX 而不是发帖。

We don't want the user to GET that url, so removing the filter is not an option for us. Instead we just wired the onclick event of the action link directly (we had to change SomePostEventHandler() slightly for this to work):

我们不希望用户获取该 url,因此删除过滤器不是我们的选择。相反,我们只是直接连接了操作链接的 onclick 事件(我们必须稍微更改 SomePostEventHandler() 才能使其工作):

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

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

So, moral of the story, for us at least, is that if you are seeing these errors, track down the URL that you THINK you are POSTing to and make sure you are.

因此,至少对我们来说,这个故事的寓意是,如果您看到这些错误,请追踪您认为要发布的 URL 并确保您是。

回答by wolfyuk

I too had this issue.

我也有这个问题。

In my case it was related to verb restrictions on the requested action, where the view was a POSTbut the partial view being requested within supported GETand HEADonly. Adding the POSTverb to the AcceptVerbsAttribute(in MVC 1.0) resolved the problem.

在我的情况下,它是关系到所请求的动作动词的限制,这里的观点是POST,但所请求的局部视图中支持GETHEAD唯一的。将POST动词添加到AcceptVerbsAttribute(在 MVC 1.0 中)解决了问题。

回答by Tuizi

I have the similar issue with qq File Upload

我有类似的问题与qq 文件上传

When the post action is /Document/SaveI get the exception A public action method 'Save' was not found on controller 'Project.Controllers.DocumentController'.

当发布操作时,/Document/Save我收到异常在控制器“Project.Controllers.DocumentController”上找不到公共操作方法“Save”。

But if the post action is /Document/Save/, the post is correct and works!

但是,如果帖子操作是/Document/Save/,则帖子是正确的并且有效!

God save the /?

上帝保佑/

回答by Zoom

From the IIS logs our problem was caused by Googlebot attempting POST and a GET for a POST only controller action.

从 IIS 日志来看,我们的问题是由 Googlebot 尝试 POST 和仅用于 POST 控制器操作的 GET 引起的。

For this case I recommend handling the 404 like Dmitriy suggestion.

对于这种情况,我建议像 Dmitriy 建议一样处理 404。

回答by C?t?lin R?doi

Remove the [HttpGet]attributes and it will work :)

删除[HttpGet]属性,它将起作用:)

回答by Valchris

The currently accepted answer does work as expected but isn't the primary use case for the feature. Instead use the feature defined by ASP.NET. In my case, I denied everything but GET and POST:

当前接受的答案确实按预期工作,但不是该功能的主要用例。而是使用 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>

With the code snippet above, MVC will correctly return a 404

使用上面的代码片段,MVC 将正确返回 404

回答by davaus

For anyone having this problem with angularjs, MVC and {{imagepath}} type inserts in image src attributes, eg:

对于 angularjs、MVC 和 {{imagepath}} 类型在图像 src 属性中插入的任何人,例如:

"A public action method '{{imagepath}}previous.png' was not found on controller"

“在控制器上找不到公共操作方法 '{{imagepath}}previous.png'”

The solution is to use ng-src instead of src.

解决方案是使用 ng-src 而不是 src。

Hope this helps someone :)

希望这对某人有所帮助:)