Aralıklı asp.net mvc istisnası: "Bir genel eylem yöntemi ABC, denetleyicide XYZ bulunamadı."


92

Asp.net mvc'nin eylem yöntemini bulamadığını söyleyen aralıklı bir istisna alıyorum. İşte istisna:

'Schoon.Form.Web.Controllers.ChrisController' denetleyicisinde 'Fill' genel eylem yöntemi bulunamadı.

Yönlendirmeyi doğru kurduğumu düşünüyorum çünkü bu uygulama çoğu zaman çalışıyor. İşte denetleyicinin eylem yöntemi.

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

Rota:

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

Ve işte yığın:

System.Web.HttpException: 'Schoon.Form.Web.Controllers.ChrisController' denetleyicisinde 'Fill' genel eylem yöntemi bulunamadı. C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: satır 197 içinde System.Web.Mvc.Controller.HandleUnknownAction (String actionName) C: System.Web.Mvc.Controller.ExecuteCore () : \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: satır 164, System.Web.Mvc.ControllerBase.Execute (RequestContext requestContext) in C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs: System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext) adresindeki ControllerBase.cs: satır 76, C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs: satır 87 C: System.Web.Mvc.MvcHandler.ProcessRequest (HttpContextBase httpContext) adresinde:

İşte filtrelerimin hepsi aynı şekilde çalışan bir örnek:

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

Teşekkürler, Chris


28
Yukarıdaki istisnayı ararken Google'da ortaya çıkan ilk sonuç olduğu için burada kayda değer olduğunu düşündüğüm benzer bir sorun yaşadım. Başvurum geçersiz bir form gönderirken bu istisnayı attı. Bunun nedeni, RenderAction'ı çağıran (yeniden) oluşturulan sayfanın ve kısmi bir görünümü oluşturmak için çağrılan eylemin HttpGet özniteliğiyle işaretlenmiş olmasından kaynaklanıyordu, bu özniteliğin kaldırılması sorunu çözdü.
s1mm0t

3
Bu davranışı da fark ettim - belki de PartialViewResults döndüren denetleyici yöntemlerine herhangi bir Http özniteliği uygulamamak en iyisidir.
Stuart

1
@ s1mm0t: doğru. benim durumum için, yorumu sorunu çözdü
Mazdak Shojaie

@ s1mm0t - lütfen bana hemen posta adresinizi gönderin. Bu Noel'de sizin için bir şişe viski geliyor !!!!!
Shane

Benzer bir şey bulduk: bazı durumlarda soruna, o eyleme yönlendirme yerine başka bir işlem sonucunu döndürmek soruna neden oluyordu. Ex çalıştığı PostSomething { return HomePageActionMethod() }yerde başarısız olur PostSomething { return RedirectToAction(nameof(HomePageActionMethod)); }. (bizim durumumuzda, görünümdeki rahatsız edici eylem farklı bir denetleyicide bulunur ve büyük olasılıkla denetleyici, ilk arama yöntemiyle tam olarak başlatılmamıştır.
jleach

Yanıtlar:


62

Cevabı bulduk. Web günlüklerimize baktık. OPTIONS, PROPFIND ve HEAD gibi bazı garip http eylemleri (fiiller / yöntemler) aldığımızı gösterdi.

Bu, bazı tez istisnalarının nedeni gibi görünüyor. Bu, neden aralıklı olduğunu açıklıyor.

Sorunu curl.exe aracıyla yeniden oluşturduk:

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

Kullandığımız düzeltme, web.config'e bir yetkilendirme bölümü eklemekti:

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

3
Ayrıca botların bazen sitenizi - ve hatta javascript - bağlantıları bulmak için tarayacağını da bulduk. Daha sonra bu URI'lara yanlış HTTP fiiliyle istek göndermeye çalışırlar. Örneğin, bir eylem için bir jQuery çağrınız varsa - örneğin / bir eylem ve bu yöntem bir POST gerektirir, bot bir GET göndermeye çalışabilir ve bu da bu hatanın ortaya çıkmasına neden olur. Durumun bu olup olmadığını doğrulamak için web günlükleriniz kesinlikle yardımcı olabilir. Googlebot'un bunu yaptığını bile görüyoruz.
jakejgordon

Aynı hatayı yalnızca Canlı sunucuda (IIS 7.5) yaşıyorum. Dağıtım, geliştirme makinemde ve başka bir destek makinesinde iyi çalışıyor. bu fiilleri eklemek ve HttpGet'i kaldırmak sorunu çözmedi. Başka önerileriniz varsa lütfen.
bjan

Gelen HEAD isteklerini reddetmeye bir alternatif olarak, uygun bir yanıt vermek isteyebilirsiniz. Bkz stackoverflow.com/a/3197128/12484
Jon Schneider

15

Benzer bir sorunla karşılaştık, ancak bunun bir kullanıcının oturum açma işlemi zaman aşımına uğradıktan sonra bir denetleyiciye gönderi göndermesinden kaynaklandığını gördük. Sistem daha sonra giriş ekranına yönlendirildi. Oturum açtıktan sonra, kullanıcının göndermeye çalıştığı URL'ye yeniden yönlendirildi, ancak bu sefer bunun yerine bir GET isteği yapıyordu ve bu nedenle [HttpPost] özniteliğiyle işaretlenmiş eylemi bulamıyordu.


Mevcut çözümüm, her zaman bir eylemin sonunda Dizin eylemine geri yönlendirme yapmaktır. Geç cevap için özür dilerim.
Johann Strydom

7

Asp.net mvc'de de aynı sorunu yaşıyorum. bu hata - 404 bulunamadı. Sorunu bu şekilde çözüyorum - bu kodu MyAppControllerBase(MVC) içine koyun

    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

Uygulamamızda da aynı sorunu yaşadık ve bunu bir javascript / jquery sorununa kadar izleyebildim. Uygulamamızda Html.ActionLink () kullanılarak tanımlanan ve daha sonra jquery tarafından POST'lara geçersiz kılınan bağlantılarımız var.

İlk önce bağlantıyı tanımlamıştık:

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

Daha sonra, SomePostEventHandler fonksiyonumuzla varsayılan eylemi geçersiz kılıyoruz:

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

Bu, HttpPost filtresine sahip MVC eylemimize çarpıyordu:

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

Bulduğumuz şey, çoğu zaman bunun harika çalıştığı. Bununla birlikte, bazı yavaş sayfa yüklemelerinde (veya gerçekten hızlı kullanıcılar), kullanıcı jquery $ (document) .ready () olayından önce bağlantıya tıklıyordu, yani GET / Controller / SomeAction / XX yerine gönderme.

Kullanıcının bu url'yi ALMASINI istemiyoruz, bu nedenle filtreyi kaldırmak bizim için bir seçenek değil. Bunun yerine, eylem bağlantısının onclick olayını doğrudan kabloladık (bunun çalışması için SomePostEventHandler () biraz değiştirmemiz gerekiyordu):

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

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

Öyleyse, en azından bizim için hikayenin ahlaki değeri, bu hataları görüyorsanız, YAYINLADIĞINIZI DÜŞÜNÜYORSUNUZ URL'yi takip edin ve olduğunuzdan emin olun.


Genel olarak, bir html hiperlinkinden POST yaparken dikkatli olmalısınız. Kullanıcıyı başka bir sayfaya (http almak) götürmek için köprüler mevcuttur ve html düğmeleri bir form (http gönderisi) göndermelidir.
stevie_c

2

Bende de bu sorun vardı.

Benim durumumda, görünümün bir olduğu, POSTancak desteklenen GETve HEADyalnızca kısmi görünümün talep edildiği, istenen eylemdeki fiil kısıtlamalarıyla ilgiliydi . POSTFiilin AcceptVerbsAttribute(MVC 1.0'da) eklenmesi sorunu çözdü.


2

IIS günlüklerinden, sorunumuz Googlebot’un POST denemesinden ve yalnızca POST denetleyici eylemi için GET’den kaynaklanıyordu.

Bu durum için 404'ü Dmitriy önerisi gibi ele almanızı tavsiye ederim.


1

Şu anda kabul edilen cevap beklendiği gibi çalışıyor ancak özelliğin birincil kullanım durumu değil. Bunun yerine ASP.NET tarafından tanımlanan özelliği kullanın. Benim durumumda, GET ve POST dışında her şeyi reddettim:

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

Yukarıdaki kod parçacığı ile MVC doğru bir şekilde 404 döndürür


0

Olmamalı

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

Ayrıca, filtreleriniz ne işe yarar? ActionMethodSelectorAttribute gibi eylemi gizleyemezler mi?


Bu bir düzenleme hatasıdır. Masumları korumaya çalışıyordum.
Chris Schoon

Bazı parametreleri doldururlar. Örneğin, UserIdFilter, kullanıcı kimliğini oturumdan / tanımlama bilgisinden / vb. Almak için bir yardımcıdır. İlk parametreyi doldurur. Gönderiyi içerecek şekilde düzenleyeceğim.
Chris Schoon

0

Qq Dosya Yükleme ile benzer bir sorun yaşıyorum

Post eylemi olduğunda /Document/Saveistisnayı alıyorum 'Project.Controllers.DocumentController' denetleyicisinde bir genel eylem yöntemi 'Kaydet' bulunamadı.

Ancak gönderi eylemi ise /Document/Save/, gönderi doğrudur ve işe yaramaktadır!

Tanrı korusun / ?


0

Temel nedenim yorumda belirtilenle benzerdi.

Ben ajaxSubmittingbir düğmeye tıklayarak üzerine bir formu. Form alanlarından biri tipteydi Date. Ancak, istemci ve sunucu makine arasındaki tarih biçimlerindeki farklılık nedeniyle, denetleyicide POST yöntemini çalıştırmadı. Sunucu bir 302yanıt gönderdi ve ardından GETaynı yöntem için tekrar bir istek gönderdi .

Ancak, denetleyicideki eylem HttpPostöznitelikle süslendi ve bu nedenle yöntemi bulamadı ve bir 404yanıt gönderdi .

Kodu, Tarih formatlarındaki uyumsuzluğun bir hataya neden olmayacağı şekilde düzelttim ve sorun giderildi.


0

[HttpGet]Öznitelikleri kaldırın ve işe yarayacaktır :)


Bu, hataları "çözerken", sizin (veya önünüzdeki birinin) [HttpGet]eylemlerin başka bir FİİL yoluyla çağrılmasını önlemek için bu nitelikleri oraya kasten koyma olasılığı vardır
Nick Orlando

0

Angularjs, MVC ve {{imagepath}} türü görüntü src özniteliklerinde bu sorunu yaşayan herkes için, örneğin:

"Denetleyicide '{{imagepath}} previous.png' 'genel işlem yöntemi bulunamadı"

Çözüm, src yerine ng-src kullanmaktır.

Umarım bu birine yardımcı olur :)


neredeyse bir yıl sonra, bunu arıyordum :) tnx!
Verthosa

0

Söz konusu URL'ye göz atmanın hatayı yeniden oluşturmak için yeterli olup olmadığına bakın. Eylem yalnızca bir POST eylemi olarak tanımlansaydı olurdu. Bunu yapmak, hatayı istediğiniz zaman yeniden oluşturmanıza olanak tanır.

Her durumda, hatayı genel olarak aşağıdaki gibi halledebilirsiniz. Buradaki başka bir cevap HandleUnknownAction, kötü denetleyici adlarını değil, yalnızca kötü eylem adlarına sahip URL'leri ele alır. Aşağıdaki yaklaşım her ikisini de ele almaktadır.

Bunu temel denetleyicinize ekleyin (kodu burada gösterilmez):

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

Global.asax.cs'ye, yukarıdaki yöntemi çağıran veya yakalanan 404 hatasıyla yapmak istediğiniz her şeyi yapan genel bir istisna işleyicisi ekleyin:

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));
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.