ข้อยกเว้น mvc asp.net แบบไม่ต่อเนื่อง:“ ไม่พบวิธีการดำเนินการสาธารณะ ABC บนคอนโทรลเลอร์ XYZ”


92

ฉันได้รับข้อยกเว้นไม่ต่อเนื่องโดยแจ้งว่า asp.net mvc ไม่พบวิธีการดำเนินการ นี่คือข้อยกเว้น:

ไม่พบวิธีการดำเนินการสาธารณะ 'Fill' ในตัวควบคุม 'Schoon.Form.Web.Controllers.ChrisController'

ฉันคิดว่าฉันตั้งค่าการกำหนดเส้นทางอย่างถูกต้องเนื่องจากแอปพลิเคชันนี้ใช้งานได้เกือบตลอดเวลา นี่คือวิธีการดำเนินการของคอนโทรลเลอร์

[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: ไม่พบวิธีการดำเนินการสาธารณะ 'Fill' บนตัวควบคุม 'Schoon.Form.Web.Controllers.ChrisController' ที่ System.Web.Mvc.Controller.HandleUnknownAction (String actionName) ใน C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: บรรทัดที่ 197 ที่ System.Web.Mvc.Controller.ExecuteCore () ใน C : \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ Controller.cs: บรรทัดที่ 164 ที่ System.Web.Mvc.ControllerBase.Execute (RequestContext requestContext) ใน C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs: บรรทัดที่ 76 ที่ System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext) ใน C: \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs: บรรทัด 87 ที่ System.Web.Mvc.MvcHandler.ProcessRequest (HttpContextBase httpContext) ใน C:

นี่คือตัวอย่างตัวกรองของฉันซึ่งทั้งหมดทำงานในลักษณะเดียวกัน:

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

ขอบคุณคริส


28
ฉันมีปัญหาที่คล้ายกันซึ่งฉันคิดว่าน่าสังเกตที่นี่เนื่องจากนี่เป็นผลลัพธ์แรกที่เกิดขึ้นใน Google เมื่อค้นหาข้อยกเว้นข้างต้น ใบสมัครของฉันมีข้อยกเว้นนี้เมื่อส่งแบบฟอร์มที่ไม่ถูกต้อง นี่เป็นเพราะหน้าที่ถูก (re-) แสดงการเรียก RenderAction และการดำเนินการที่เรียกให้แสดงผลมุมมองบางส่วนถูกทำเครื่องหมายด้วยแอตทริบิวต์ HttpGet การลบแอตทริบิวต์นี้ช่วยแก้ปัญหาได้
s1mm0t

3
ฉันสังเกตเห็นพฤติกรรมนี้เช่นกัน - อาจเป็นการดีที่สุดที่จะไม่ใช้แอตทริบิวต์ Http ใด ๆ กับวิธีการควบคุมที่ส่งคืน PartialViewResults
สจวร์ต

1
@ s1mm0t: ถูกต้อง สำหรับกรณีของฉันความคิดเห็นของเขาช่วยแก้ปัญหาได้
Mazdak Shojaie

@ s1mm0t - โปรดส่งที่อยู่ไปรษณีย์ของคุณมาให้ฉันทันที สก็อตสักขวดกำลังจะมาถึงคุณในคริสต์มาสนี้ !!!!!
เชน

เราพบสิ่งที่คล้ายกัน: ในบางกรณีส่งคืนการดำเนินการอื่นผลลัพธ์แทนที่จะเปลี่ยนเส้นทางไปยังการกระทำนั้นทำให้เกิดปัญหา เช่นPostSomething { return HomePageActionMethod() }ล้มเหลวในที่PostSomething { return RedirectToAction(nameof(HomePageActionMethod)); }ทำงาน (ในกรณีของเราการกระทำที่ไม่เหมาะสมในมุมมองนั้นอยู่ในตัวควบคุมอื่นและสันนิษฐานว่าคอนโทรลเลอร์ไม่ได้เริ่มต้นอย่างสมบูรณ์ด้วยวิธีการโทรครั้งแรก
jleach

คำตอบ:


62

เราพบคำตอบแล้ว เราตรวจสอบบันทึกการใช้งานเว็บของเรา แสดงให้เห็นว่าเราได้รับการกระทำ http (คำกริยา / วิธีการ) แปลก ๆ เช่น OPTIONS, PROPFIND และ HEAD

นี่ดูเหมือนจะเป็นสาเหตุของข้อยกเว้นบางประการ สิ่งนี้อธิบายว่าเหตุใดจึงไม่ต่อเนื่อง

เราทำให้ปัญหาเกิดขึ้นอีกครั้งกับเครื่องมือ 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>

3
นอกจากนี้เรายังพบว่าบางครั้งบอทจะรวบรวมข้อมูลเว็บไซต์ของคุณและแม้แต่จาวาสคริปต์เพื่อค้นหาลิงก์ จากนั้นลองส่งคำขอไปยัง URI เหล่านี้ด้วยคำกริยา HTTP ที่ไม่ถูกต้อง ตัวอย่างเช่นหากคุณมีการเรียก jQuery ให้ดำเนินการบางอย่างเช่น / some-action และวิธีนี้ต้องใช้ POST บอทอาจพยายามส่ง GET ซึ่งจะทำให้เกิดข้อผิดพลาดนี้ขึ้น บันทึกเว็บของคุณสามารถช่วยยืนยันได้อย่างแน่นอนว่าเป็นกรณีนี้หรือไม่ เรายังเห็น googlebot ทำเช่นนี้
jakejgordon

ฉันมีข้อผิดพลาดเดียวกันนี้เฉพาะบนเซิร์ฟเวอร์ Live (IIS 7.5) การปรับใช้งานทำงานได้ดีบนเครื่องพัฒนาของฉันรวมถึงเครื่องสนับสนุนอื่น การเพิ่มคำกริยาเหล่านี้และการลบ HttpGet ไม่ได้ช่วยแก้ปัญหา โปรดมีข้อเสนอแนะเพิ่มเติม
bjan

อีกทางเลือกหนึ่งในการปฏิเสธคำขอ HEAD ที่เข้ามาคุณอาจต้องการตอบสนองที่เหมาะสม ดูstackoverflow.com/a/3197128/12484
Jon Schneider

15

เรามีปัญหาที่คล้ายกัน แต่พบว่าเกิดขึ้นเนื่องจากผู้ใช้โพสต์ไปยังตัวควบคุมหลังจากที่การเข้าสู่ระบบหมดเวลา จากนั้นระบบจะเปลี่ยนเส้นทางไปยังหน้าจอเข้าสู่ระบบ หลังจากเข้าสู่ระบบแล้วระบบจะเปลี่ยนเส้นทางกลับไปยัง URL ที่ผู้ใช้พยายามโพสต์ไป แต่คราวนี้กำลังส่งคำขอ GET แทนดังนั้นจึงไม่พบการดำเนินการที่ถูกทำเครื่องหมายด้วยแอตทริบิวต์ [HttpPost]


วิธีแก้ปัญหาปัจจุบันของฉันไกลที่สุดเท่าที่จะทำได้ในการเปลี่ยนเส้นทางกลับไปที่การดำเนินการดัชนีเมื่อสิ้นสุดการดำเนินการ ขอโทษที่ตอบช้า.
Johann Strydom

7

ฉันมีปัญหาเดียวกันใน 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();
    }

6

เราเพิ่งมีปัญหาเดียวกันในแอปพลิเคชันของเราและฉันสามารถติดตามมันไปยังปัญหา javascript / jquery เรามีลิงก์ในแอปพลิเคชันของเราที่กำหนดโดยใช้ Html.ActionLink () ซึ่งจะถูกแทนที่ใน POST ในภายหลังโดย jquery

ก่อนอื่นเราได้กำหนดลิงค์:

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

ต่อมาเราจะแทนที่การกระทำเริ่มต้นด้วยฟังก์ชัน SomePostEventHandler ของเรา:

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

นี่เป็นการกดปุ่มการกระทำ MVC ของเราที่มีตัวกรอง HttpPost:

 [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 ที่คุณคิดว่าคุณกำลังโพสต์และตรวจสอบให้แน่ใจว่าคุณเป็น


โดยทั่วไปคุณควรระมัดระวังเมื่อคุณโพสต์จากไฮเปอร์ลิงก์ html มีการเชื่อมโยงหลายมิติเพื่อนำผู้ใช้ไปยังหน้าอื่น (http get) และปุ่ม html ควรส่งแบบฟอร์ม (โพสต์ http)
stevie_c

2

ฉันก็มีปัญหานี้เช่นกัน

ในกรณีของฉันมันเกี่ยวข้องกับข้อ จำกัด ของคำกริยาในการดำเนินการที่ร้องขอโดยที่ข้อมูลพร็อพเพอร์ตี้นั้นเป็นPOSTข้อมูลพร็อพเพอร์ตี้ แต่เป็นการร้องขอบางส่วนภายในได้รับการสนับสนุนGETและHEADเท่านั้น การเพิ่มPOSTคำกริยาลงในAcceptVerbsAttribute(ใน MVC 1.0) ช่วยแก้ปัญหาได้


2

จากบันทึก IIS ปัญหาของเราเกิดจาก Googlebot พยายาม POST และ GET สำหรับการทำงานของตัวควบคุม POST เท่านั้น

สำหรับกรณีนี้ฉันขอแนะนำให้จัดการข้อเสนอแนะ 404 เช่น Dmitriy


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 อย่างถูกต้อง


0

มันไม่ควร

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

นอกจากนี้ตัวกรองของคุณทำอะไร พวกเขาไม่สามารถซ่อนการกระทำเช่น ActionMethodSelectorAttribute ได้หรือไม่?


นั่นคือความผิดพลาดในการแก้ไข ฉันพยายามปกป้องผู้บริสุทธิ์
Chris Schoon

พวกเขาเติมพารามิเตอร์บางส่วน ตัวอย่างเช่น UserIdFilter เป็นตัวช่วยในการรับ ID ผู้ใช้จากเซสชัน / คุกกี้ / ฯลฯ โดยจะเติมพารามิเตอร์ตัวแรก ฉันจะแก้ไขโพสต์เพื่อรวมไว้
Chris Schoon

0

ฉันมีปัญหาคล้ายกันกับqq File Upload

เมื่อการดำเนินการโพสต์/Document/Saveฉันได้รับข้อยกเว้นไม่พบวิธีการดำเนินการสาธารณะ 'บันทึก' ในคอนโทรลเลอร์ 'Project.Controllers.DocumentController'

แต่ถ้าการดำเนิน/Document/Save/การโพสต์นั้นโพสต์นั้นถูกต้องและใช้งานได้

พระเจ้าช่วย/ ?


0

สาเหตุที่แท้จริงของฉันคล้ายกับที่กล่าวถึงในความคิดเห็น

ฉันajaxSubmittingเป็นแบบฟอร์มเมื่อคลิกปุ่ม Dateหนึ่งในเขตข้อมูลแบบฟอร์มได้จากประเภท อย่างไรก็ตามเนื่องจากความแตกต่างในรูปแบบวันที่ระหว่างไคลเอนต์และเครื่องเซิร์ฟเวอร์จึงไม่ได้ดำเนินการเมธอด POST ในคอนโทรลเลอร์ เซิร์ฟเวอร์ส่งการ302ตอบกลับกลับมาแล้วส่งGETคำร้องขอวิธีเดิมอีกครั้ง

อย่างไรก็ตามการดำเนินการในคอนโทรลเลอร์ได้รับการตกแต่งด้วยHttpPostแอตทริบิวต์ดังนั้นจึงไม่พบวิธีการและส่งการ404ตอบกลับกลับไป

ฉันเพิ่งแก้ไขรหัสเพื่อให้รูปแบบวันที่ไม่ตรงกันจะไม่ทำให้เกิดข้อผิดพลาดและปัญหาได้รับการแก้ไขแล้ว


0

ลบ[HttpGet]แอตทริบิวต์และจะใช้งานได้ :)


แม้ว่าจะ "แก้ไข" ข้อผิดพลาดนี้ แต่ความเป็นไปได้ก็คือคุณ (หรือใครบางคนก่อนหน้าคุณ) ใส่[HttpGet]แอตทริบิวต์เหล่านั้นไว้ที่จุดประสงค์เพื่อป้องกันไม่ให้มีการเรียกการดำเนินการผ่าน VERB อื่น ๆ
Nick Orlando

0

สำหรับใครก็ตามที่มีปัญหานี้กับการแทรกประเภท angularjs, MVC และ {{imagepath}} ในแอตทริบิวต์ image src เช่น:

"ไม่พบวิธีการดำเนินการสาธารณะ" {{imagepath}} previous.png "ในคอนโทรลเลอร์"

วิธีแก้คือใช้ ng-src แทน src

หวังว่านี่จะช่วยใครสักคน :)


เกือบหนึ่งปีต่อมาฉันกำลังมองหาสิ่งนี้ :) tnx!
Verthosa

0

ดูว่าการเรียกดู 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));
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.