web-dev-qa-db-ja.com

断続的なasp.net mvc例外:「コントローラーXYZでパブリックアクションメソッドABCが見つかりませんでした。」

Asp.net mvcがアクションメソッドを見つけられないという断続的な例外が発生しています。例外は次のとおりです。

コントローラー 'Schoon.Form.Web.Controllers.ChrisController'でパブリックアクションメソッド 'Fill'が見つかりませんでした。

このアプリケーションはほとんどの場合機能するため、ルーティングが正しく設定されていると思います。これがコントローラーのアクションメソッドです。

[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'でパブリックアクションメソッド 'Fill'が見つかりませんでした。 C:\ dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\Controller.cs:System.Web.Mvc.Controller.ExecuteCore()のSystem.Web.Mvc.Controller.HandleUnknownAction(String actionName)で:\ 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\C:\ dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\ControllerBase.cs:line 87のSystem.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)のControllerBase.cs:line 76 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)at C:\ dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs:line 80 at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) C:\ dev\ThirdParty\MvcDev\src\SystemWebMvc\Mvc\MvcHandler.cs:System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext)at C:\ dev\ThirdParty\MvcDev\src\SystemWebMvc\Mv System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()at System.Web.HttpApplication.ExecuteStep(IExecutionStep step、Boolean&completedSynchronously)のc\MvcHandler.cs:line 104

以下に、すべて同じように機能するフィルターの例を示します。

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

ありがとう、クリス

89
Chris Schoon

答えが見つかりました。 Webログを調べました。 OPTIONS、PROPFIND、HEADなどの奇妙なhttpアクション(動詞/メソッド)を受け取っていることがわかりました。

これは、これらの例外の一部の原因と思われます。これが断続的な理由を説明しています。

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>
60
Chris Schoon

同様の問題がありましたが、ログインがタイムアウトした後にユーザーがコントローラーに投稿していたために発生していることがわかりました。その後、システムはログイン画面にリダイレクトされました。ログイン後、ユーザーが投稿しようとしていたURLにリダイレクトされましたが、今回は代わりにGETリクエストを行っていたため、[HttpPost]属性でマークされたアクションが見つかりませんでした。

15
Johann Strydom

私は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();
    }
7
Dmitriy

アプリケーションで同じ問題が発生したため、javascript/jqueryの問題を追跡できました。 Html.ActionLink()を使用して定義されたアプリケーションのリンクは、jqueryによってPOSTに後でオーバーライドされます。

最初にリンクを定義しました:

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

後で、SomePostEventHandler関数を使用してデフォルトアクションをオーバーライドします。

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

これは、HttpPostフィルターを持つMVCアクションにヒットしていました。

 [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を追跡し、自分がいることを確認することです。

6
jslatts

私もこの問題を抱えていました。

私の場合、ビューはPOSTでしたが、サポートされているGETおよびHEADのみで要求されている部分ビューである、要求されたアクションの動詞制限に関連していました。 POST動詞をAcceptVerbsAttributeに追加すると(MVC 1.0で)問題が解決しました。

2
WolfyUK

[HttpGet]属性を削除すると動作します:)

1

現在受け入れられている回答は期待どおりに機能しますが、この機能の主な使用例ではありません。代わりに、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
Valchris

qq File Upload で同様の問題があります

投稿アクションが/Document/Save例外が発生しましたコントローラー 'Project.Controllers.DocumentController'でパブリックアクションメソッド 'Save'が見つかりませんでした。

ただし、投稿アクションが/Document/Save/、投稿は正しく、機能しています。

神は/を救う?

1
Tuizi

IISログから、私たちの問題はGooglebotがPOSTと、POSTコントローラーアクションのみを試みているために発生しました。

この場合、Dmitriyの提案のように404を処理することをお勧めします。

1
Zoom

私の根本的な原因は、コメントで言及されたものと似ていました。

私はajaxSubmittingボタンをクリックしたときのフォームでした。フォームフィールドの1つはDate型でした。ただし、クライアントとサーバーマシンの日付形式が異なるため、コントローラーでPOSTメソッドを実行しませんでした。サーバーは302応答してから、同じメソッドに対してGET要求を再度送信しました。

ただし、コントローラーのアクションはHttpPost属性で装飾されているため、メソッドが見つからず、404応答。

日付形式の不一致がエラーを引き起こさないようにコードを修正し、問題を修正しました。

0
mridula

すべきではない

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

また、フィルターは何をしますか? ActionMethodSelectorAttributeなどのアクションを非表示にできませんか?

0
queen3

Anglejs、MVC、および{{imagepath}}タイプでこの問題を抱えている人のために、画像のsrc属性にタイプを挿入します。

「パブリックアクションメソッド '{{imagepath}} previous.png'がコントローラーで見つかりませんでした」

解決策は、srcの代わりにng-srcを使用することです。

これが誰かを助けることを願っています:)

0
davaus

問題の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));
    }
}
0
Tawab Wakil