간헐적 인 asp.net mvc 예외 : "공개 작업 방법 ABC를 컨트롤러 XYZ에서 찾을 수 없습니다."
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 : line 197의 System.Web.Mvc.Controller.HandleUnknownAction (String actionName)에서 C의 System.Web.Mvc.Controller.ExecuteCore ()에서 : \ 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의 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext) in C : \ dev \ ThirdParty \ MvcDev \ src \ SystemWebMvc \ Mvc \ ControllerBase.cs : line 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);
}
}
고마워, 크리스
답을 찾았습니다. 우리는 웹 로그를 조사했습니다. 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>
비슷한 문제가 있었지만 사용자가 로그인 시간이 초과 된 후 컨트롤러에 게시했기 때문에 문제가 발생했습니다. 그런 다음 시스템이 로그인 화면으로 리디렉션됩니다. 로그인 후 사용자가 게시하려는 URL로 다시 리디렉션되었지만 이번에는 대신 GET 요청을 수행했기 때문에 [HttpPost] 속성으로 표시된 작업을 찾지 못했습니다.
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)
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();
}
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.
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:
$(document).ready(function() {
$('#MyLink').click(SomePostEventHandler);
}
This was hitting our MVC action that had a HttpPost filter:
[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.
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):
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.
I too had this issue.
In my case it was related to verb restrictions on the requested action, where the view was a POST
but the partial view being requested within supported GET
and HEAD
only. Adding the POST
verb to the AcceptVerbsAttribute
(in MVC 1.0) resolved the problem.
I have the similar issue with qq File Upload
When the post action is /Document/Save
I get the exception A public action method 'Save' was not found on controller 'Project.Controllers.DocumentController'.
But if the post action is /Document/Save/
, the post is correct and works!
God save the / ?
From the IIS logs our problem was caused by Googlebot attempting POST and a GET for a POST only controller action.
For this case I recommend handling the 404 like Dmitriy suggestion.
Remove the [HttpGet]
attributes and it will work :)
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:
<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
Shouldn't it be
routes.MapRoute(
"SchoonForm",
"Form/Fill/{subscriberId}",
new { controller = "Chris", action = "Fill" },
Also, what do your filters do? Can't they hide action, like ActionMethodSelectorAttribute?
My root cause was similar to the one mentioned in the comment.
I was ajaxSubmitting
a form upon the click of a button. One of the form fields was of type Date
. However, because of the difference in the date formats between the client and server machine it did not execute the POST method in the controller. The server sent back a 302
response and then sent a GET
request for the same method again.
However, the action in the controller was decorated with the HttpPost
attribute and hence it could not find the method and sent back a 404
response.
I just fixed the code such that the mismatch in the Date formats would not cause an error and the problem was fixed.
For anyone having this problem with angularjs, MVC and {{imagepath}} type inserts in image src attributes, eg:
"A public action method '{{imagepath}}previous.png' was not found on controller"
The solution is to use ng-src instead of src.
Hope this helps someone :)
See if simply browsing to the URL in question is enough to reproduce the error. It would if the action was only defined as a POST action. Doing this allows you to reproduce the error at will.
In any case, you can globally handle the error as below. Another answer here that references HandleUnknownAction
only handles URLs with bad action names, not bad controller names. The following approach handles both.
Add this to your base controller (view code omitted here):
public ActionResult Error(string errorMessage)
{
return View("Error"); // or do something like log the error, etc.
}
Add a global exception handler to Global.asax.cs that calls the method above or does whatever else you want to do with the caught 404 error:
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));
}
}
'code' 카테고리의 다른 글
obj 폴더는 무엇을 위해 생성됩니까? (0) | 2020.09.08 |
---|---|
JQuery에 권장되는 JavaScript HTML 템플릿 라이브러리? (0) | 2020.09.08 |
python numpy.where ()는 어떻게 작동합니까? (0) | 2020.09.08 |
slf4j에서 런타임시 메시지의 로그 수준 설정 (0) | 2020.09.08 |
WPF에서 탭 순서 설정 (0) | 2020.09.07 |