我得到一个间歇性的例外,说asp.net mvc找不到动作方法。这是例外:
公共行动方法'填充'可以 在控制器上找不到 '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:公共 动作方法'填充'不能 在控制器上找到 'Schoon.Form.Web.Controllers.ChrisController'。 在 System.Web.Mvc.Controller.HandleUnknownAction(字符串 actionName)in C:\ dev的\第三方\ MvcDev \ SRC \ SystemWebMvc \的mvc \ Controller.cs:线 197年 System.Web.Mvc.Controller.ExecuteCore() 在 C:\ dev的\第三方\ MvcDev \ SRC \ SystemWebMvc \的mvc \ Controller.cs:线 164点 System.Web.Mvc.ControllerBase.Execute(的RequestContext requestContext)in C:\ dev的\第三方\ MvcDev \ SRC \ SystemWebMvc \的mvc \ ControllerBase.cs:线 76点 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(的RequestContext requestContext)in C:\ dev的\第三方\ MvcDev \ SRC \ SystemWebMvc \的mvc \ ControllerBase.cs:线 87点 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)中 C:\ dev的\第三方\ MvcDev \ SRC \ SystemWebMvc \的mvc \ MvcHandler.cs:线 80点 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext的 httpContext)中 C:\ dev的\第三方\ MvcDev \ SRC \ SystemWebMvc \的mvc \ MvcHandler.cs:线 68点 System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext的 httpContext)中 C:\ dev的\第三方\ MvcDev \ SRC \ SystemWebMvc \的mvc \ MvcHandler.cs:线 104点 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在 System.Web.HttpApplication.ExecuteStep(IExecutionStep 步,布尔& completedSynchronously)
以下是我的过滤器示例,它们的工作方式相同:
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);
}
}
谢谢, 克里斯
答案 0 :(得分:60)
我们找到了答案。我们调查了我们的网络日志。它表明我们收到了一些奇怪的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>
答案 1 :(得分:15)
我们遇到了类似的问题,但发现它发生的原因是用户在登录超时后发布到控制器。然后系统重定向到登录屏幕。登录后,它会重定向回用户尝试发布的URL,但这次它正在执行GET请求,因此找不到标有[HttpPost]属性的操作。
答案 2 :(得分: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();
}
答案 3 :(得分:6)
我们在应用程序上遇到了同样的问题,我能够将其跟踪到javascript / jquery问题。我们在使用Html.ActionLink()定义的应用程序中有链接,这些链接稍后被jquery覆盖到POST中。
首先我们定义了链接:
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而不是张贴。
我们不希望用户获取该网址,因此删除过滤器不是我们的选择。相反,我们直接连接了动作链接的onclick事件(我们必须稍微更改SomePostEventHandler()才能使其工作):
string clickEvent = "return SomePostEventHandler(this);";
Html.ActionLink("Click Me", "SomeAction", new { id = Model.Id}, new { onclick = clickEvent })
因此,至少对我们来说,故事的道德之处在于,如果您看到这些错误,请追踪您认为自己正在发布的网址,并确保确实存在。
答案 4 :(得分:2)
我也有这个问题。
在我的情况下,它与所请求操作的动词限制相关,其中视图为POST
,但仅在受支持的GET
和HEAD
内请求部分视图。将POST
动词添加到AcceptVerbsAttribute
(在MVC 1.0中)解决了这个问题。
答案 5 :(得分:1)
当帖子操作为/Document/Save
时,我收到异常在控制器'Project.Controllers.DocumentController'上找不到公共操作方法'保存'。
但如果帖子操作为/Document/Save/
,则帖子是正确的并且有效!
上帝保存 / ?
答案 6 :(得分:1)
从IIS日志中,我们的问题是由Googlebot尝试POST而GET仅为POST控制器操作引起的。
对于这种情况,我建议像Dmitriy建议一样处理404。
答案 7 :(得分:1)
删除[HttpGet]
属性,它将起作用:)
答案 8 :(得分: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
答案 9 :(得分:0)
不应该是
routes.MapRoute(
"SchoonForm",
"Form/Fill/{subscriberId}",
new { controller = "Chris", action = "Fill" },
此外,您的过滤器有什么作用?他们不能隐藏动作,比如ActionMethodSelectorAttribute?
答案 10 :(得分:0)
我的根本原因与评论中提到的相似。
点击一个按钮,我就是ajaxSubmitting
表格。其中一个表单字段的类型为Date
。但是,由于客户端和服务器计算机之间的日期格式不同,它没有在控制器中执行POST方法。服务器发回302
响应,然后再次发送GET
请求相同的方法。
但是,控制器中的操作是使用HttpPost
属性修饰的,因此无法找到该方法并发回404
响应。
我刚刚修改了代码,以便日期格式中的不匹配不会导致错误并且问题已修复。
答案 11 :(得分:0)
对于任何有angularjs问题的人,MVC和{{imagepath}}类型插入图像src属性,例如:
&#34;公共行动方法&#39; {{imagepath}} previous.png&#39;在控制器&#34;
上找不到解决方案是使用ng-src而不是src。
希望这有助于某人:)
答案 12 :(得分: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));
}
}