Pengecualian mvc asp.net terputus-putus: “Metode tindakan publik ABC tidak dapat ditemukan pada pengontrol XYZ.”

92

Saya mendapatkan pengecualian intermiten yang mengatakan bahwa asp.net mvc tidak dapat menemukan metode tindakan. Berikut pengecualiannya:

Metode tindakan publik 'Isi' tidak dapat ditemukan pada pengontrol 'Schoon.Form.Web.Controllers.ChrisController'.

Saya rasa saya telah menyiapkan perutean dengan benar karena aplikasi ini berfungsi hampir sepanjang waktu. Berikut adalah metode tindakan pengontrol.

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

Rute:

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

Dan inilah tumpukannya:

System.Web.HttpException: Metode tindakan publik 'Isi' tidak dapat ditemukan pada pengontrol 'Schoon.Form.Web.Controllers.ChrisController'. di System.Web.Mvc.Controller.HandleUnknownAction (String actionName) di C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: baris 197 di System.Web.Mvc.Controller.ExecuteCore () di C : \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: baris 164 di System.Web.Mvc.ControllerBase.Execute (RequestContext requestContext) di C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs: baris 76 di System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext) di C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs: baris 87 di System.Web.Mvc.MvcHandler.ProcessRequest (HttpContextBase httpContext) di C:

Berikut adalah contoh filter saya, semuanya bekerja dengan cara yang sama:

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

Terima kasih, Chris

Chris Schoon
sumber
28
Saya memiliki masalah serupa yang menurut saya perlu diperhatikan di sini karena ini adalah hasil pertama yang muncul di Google saat mencari pengecualian di atas. Permohonan saya memberikan pengecualian ini saat mengirimkan formulir yang tidak valid. Ini karena halaman yang sedang dirender (ulang) memanggil RenderAction dan tindakan yang dipanggil untuk membuat tampilan parsial ditandai dengan atribut HttpGet, menghapus atribut ini menyelesaikan masalah.
s1mm0t
3
Saya telah memperhatikan perilaku ini juga - mungkin yang terbaik adalah tidak menerapkan atribut Http apa pun ke metode pengontrol yang mengembalikan PartialViewResults.
Stuart
1
@ s1mm0t: benar. untuk kasus saya, komentarnya memecahkan masalah
Mazdak Shojaie
@ s1mm0t - kirimkan saya alamat pos Anda segera. Sebotol Scotch sedang dalam perjalanan untukmu Natal ini !!!!!
Shane
Kami menemukan sesuatu yang serupa: dalam kasus tertentu mengembalikan hasil tindakan lain dan bukan pengalihan ke tindakan itu yang menyebabkan masalah. Ex PostSomething { return HomePageActionMethod() }gagal di tempat PostSomething { return RedirectToAction(nameof(HomePageActionMethod)); }kerja. (dalam kasus kami, tindakan yang melanggar dalam tampilan terletak di pengontrol yang berbeda, dan mungkin pengontrol tersebut tidak sepenuhnya diinisialisasi dengan metode pemanggilan pertama.
jleach

Jawaban:

62

Kami menemukan jawabannya. Kami memeriksa log web kami. Itu menunjukkan bahwa kami menerima beberapa tindakan http aneh (kata kerja / metode) seperti OPTIONS, PROPFIND, dan HEAD.

Hal ini tampaknya menjadi penyebab beberapa pengecualian tesis. Ini menjelaskan mengapa itu terputus-putus.

Kami mereproduksi masalah dengan alat 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

Perbaikan yang kami gunakan adalah menambahkan bagian otorisasi ke web.config:

<authorization>
  <deny users="*" verbs="OPTIONS, PROPFIND, HEAD"/>
</authorization>
Chris Schoon
sumber
3
Kami juga menemukan bahwa bot terkadang akan merayapi situs Anda - dan bahkan javascript - untuk menemukan tautan. Mereka kemudian mencoba mengirim permintaan ke URI ini dengan kata kerja HTTP yang salah. Misalnya, jika Anda memiliki panggilan jQuery ke beberapa tindakan - misalnya / beberapa tindakan dan metode ini memerlukan POST, bot mungkin mencoba mengirim GET, yang akan menyebabkan kesalahan ini muncul. Log web Anda pasti dapat membantu mengonfirmasi apakah ini masalahnya. Kami bahkan melihat googlebot melakukan ini.
jakejgordon
Saya mengalami kesalahan yang sama ini hanya di server Live (IIS 7.5). Penerapan berfungsi dengan baik di mesin pengembangan saya serta di mesin pendukung lain. menambahkan kata kerja ini dan menghapus HttpGet tidak memperbaiki masalah. Ada saran lebih lanjut.
bjan
Sebagai alternatif untuk menolak permintaan HEAD yang masuk, Anda mungkin ingin memberikan tanggapan yang sesuai. Lihat stackoverflow.com/a/3197128/12484
Jon Schneider
15

Kami mengalami masalah serupa, tetapi ternyata hal itu terjadi karena pengguna memposting ke pengontrol setelah waktu loginnya habis. Sistem kemudian diarahkan ke layar login. Setelah masuk, ia dialihkan kembali ke URL yang coba dikirim oleh pengguna, tetapi kali ini ia melakukan permintaan GET dan oleh karena itu tidak menemukan tindakan yang ditandai dengan atribut [HttpPost].

Johann Strydom
sumber
Solusi saya saat ini adalah sejauh mungkin untuk selalu melakukan pengalihan kembali ke tindakan Indeks di akhir tindakan. Maaf atas tanggapan yang terlambat.
Johann Strydom
7

Saya mendapat masalah yang sama di asp.net MVC. kesalahan ini - 404 tidak ditemukan. Saya menyelesaikan masalah dengan cara ini - masukkan kode ini ke 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();
    }
Dmitriy
sumber
6

Kami baru saja mengalami masalah yang sama pada aplikasi kami dan saya dapat melacaknya ke masalah javascript / jquery. Kami memiliki tautan dalam aplikasi kami yang ditentukan menggunakan Html.ActionLink () yang kemudian diganti menjadi POST oleh jquery.

Pertama kami telah menentukan tautan:

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

Kemudian kami mengganti tindakan default dengan fungsi SomePostEventHandler kami:

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

Ini mengenai tindakan MVC kami yang memiliki filter HttpPost:

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

Apa yang kami temukan adalah bahwa sebagian besar waktu ini bekerja dengan baik. Namun, pada beberapa pemuatan halaman yang lambat (atau pengguna yang sangat cepat), pengguna mengklik link sebelum peristiwa jquery $ (document) .ready () diaktifkan, artinya mereka mencoba GET / Controller / SomeAction / XX alih-alih posting.

Kami tidak ingin pengguna MENDAPATKAN url itu, jadi menghapus filter bukanlah pilihan bagi kami. Alih-alih, kami baru saja menghubungkan peristiwa onclick dari tautan tindakan secara langsung (kami harus sedikit mengubah SomePostEventHandler () agar ini berfungsi):

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

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

Jadi, moral dari cerita ini, setidaknya bagi kami, adalah jika Anda melihat kesalahan ini, lacak URL yang Anda PIKIRKAN untuk Anda POSTING dan pastikan Anda melihatnya.

jslatts.dll
sumber
Secara umum, Anda harus berhati-hati saat melakukan POST dari hyperlink html. Hyperlink ada untuk membawa pengguna ke halaman lain (http get) dan tombol html harus mengirimkan formulir (http post).
stevie_c
2

Saya juga punya masalah ini.

Dalam kasus saya itu terkait dengan pembatasan kata kerja pada tindakan yang diminta, di mana tampilan itu POSThanyalah tampilan parsial yang diminta dalam GETdan HEADhanya didukung . Menambahkan POSTkata kerja ke AcceptVerbsAttribute(dalam MVC 1.0) menyelesaikan masalah.

wolfyuk
sumber
2

Dari log IIS, masalah kami disebabkan oleh Googlebot mencoba POST dan GET untuk tindakan pengontrol hanya POST.

Untuk kasus ini saya sarankan menangani 404 like saran Dmitriy.

Perbesar
sumber
1

Jawaban yang diterima saat ini berfungsi seperti yang diharapkan tetapi bukan kasus penggunaan utama untuk fitur tersebut. Sebagai gantinya gunakan fitur yang ditentukan oleh ASP.NET. Dalam kasus saya, saya menolak semuanya kecuali GET dan POST:

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

Dengan potongan kode di atas, MVC akan mengembalikan 404 dengan benar

Valchris
sumber
0

Bukankah seharusnya begitu

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

Selain itu, apa fungsi filter Anda? Tidak bisakah mereka menyembunyikan tindakan, seperti ActionMethodSelectorAttribute?

ratu3
sumber
Itu adalah kesalahan pengeditan. Saya mencoba untuk melindungi yang tidak bersalah.
Chris Schoon
Mereka mengisi beberapa parameter. Misalnya, UserIdFilter adalah penolong untuk mendapatkan id pengguna dari sesi / cookie / dll. Ini mengisi parameter pertama. Saya akan mengedit posting untuk memasukkannya.
Chris Schoon
0

Saya memiliki masalah serupa dengan qq File Upload

Ketika tindakan posting /Document/Savesaya mendapatkan pengecualian Metode tindakan publik 'Simpan' tidak ditemukan pada pengontrol 'Project.Controllers.DocumentController'.

Tetapi jika tindakan posting adalah /Document/Save/, posting itu benar dan berfungsi!

Tuhan selamatkan / ?

Tuizi
sumber
0

Akar masalah saya mirip dengan yang disebutkan di komentar.

Saya adalah ajaxSubmittingbentuk setelah mengklik tombol. Salah satu bidang formulir adalah tipe Date. Namun, karena perbedaan dalam format tanggal antara mesin klien dan server, metode POST tidak dijalankan pada pengontrol. Server mengirim kembali 302tanggapan dan kemudian mengirim GETpermintaan untuk metode yang sama lagi.

Namun, aksi dalam pengontrol didekorasi dengan HttpPostatribut dan karenanya tidak dapat menemukan metode dan mengirim kembali 404tanggapan.

Saya baru saja memperbaiki kode sedemikian rupa sehingga ketidakcocokan dalam format Tanggal tidak akan menyebabkan kesalahan dan masalah telah diperbaiki.

mridula.dll
sumber
0

Hapus [HttpGet]atribut dan itu akan berhasil :)

Cătălin Rădoi
sumber
Meskipun ini "memecahkan" kesalahan, kemungkinannya adalah Anda (atau seseorang sebelum Anda) [HttpGet]sengaja meletakkan atribut itu di sana, untuk mencegah tindakan dipanggil melalui KATA KERJA lain
Nick Orlando
0

Untuk siapa pun yang mengalami masalah ini dengan sisipan tipe angularjs, MVC dan {{imagepath}} dalam atribut src gambar, misalnya:

"Metode tindakan publik '{{imagepath}} before.png' tidak ditemukan pada pengontrol"

Solusinya adalah dengan menggunakan ng-src, bukan src.

Semoga ini bisa membantu seseorang :)

davaus
sumber
hampir setahun kemudian, saya mencari ini :) tnx!
Verthosa
0

Lihat apakah sekadar menelusuri URL yang dipermasalahkan sudah cukup untuk mereproduksi kesalahan. Itu akan terjadi jika tindakan itu hanya didefinisikan sebagai tindakan POST. Melakukan ini memungkinkan Anda untuk mereproduksi kesalahan sesuka hati.

Bagaimanapun, Anda dapat menangani kesalahan secara global seperti di bawah ini. Jawaban lain di sini yang referensi HandleUnknownActionhanya menangani URL dengan nama tindakan buruk, bukan nama pengontrol yang buruk. Pendekatan berikut menangani keduanya.

Tambahkan ini ke pengontrol dasar Anda (kode tampilan dihilangkan di sini):

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

Tambahkan pengendali pengecualian global ke Global.asax.cs yang memanggil metode di atas atau melakukan apa pun yang ingin Anda lakukan dengan kesalahan 404 yang tertangkap:

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));
    }
}
Tawab Wakil
sumber