用 [HttpPost] 装饰时 ASP MVC 控制器操作“未找到 404”错误
Posted
技术标签:
【中文标题】用 [HttpPost] 装饰时 ASP MVC 控制器操作“未找到 404”错误【英文标题】:ASP MVC controller action '404 not found' error when decorated with [HttpPost] 【发布时间】:2015-12-27 00:09:03 【问题描述】:我有一个控制器操作方法,它看起来像这样:
public ActionResult testMethod(int id)
//do something...
//return something...
return View();
但是当我指定它应该是“发布”方法时,我得到一个“404 未找到错误”:
[HttpPost]
public ActionResult testMethod(int id)
//do something...
//return something...
return View();
我在同一个控制器中有其他控制器操作方法 - POST 和 GET,它们工作正常。但是这个没有?这是怎么回事? (我确定我在这里遗漏了一些明显的东西......)
更新: ajax 调用请求控制器方法: var id = 1;
$.ajax(
url: '/indices/testMethod/',
data: id,
type: 'POST',
success: function (data)
//Do something
);
我还尝试使用 Postman 测试该方法,确保发送了 POST 请求。
更新 2: 我尝试将参数更改为 id,并尝试确保所有方法和 url 位置都大写以匹配,但没有任何效果。
在 Fiddler 中,我可以看到实际上正在发出一个 GET 请求,即使我在 ajax 调用中指定了一个 POST 请求,所以现在我需要找出为什么请求最终以 GET 而不是作为发布。
我也试过包含一个属性路由描述,像这样
[HttpPost]
[Route("indices/TestMethod/id:int")]
public ActionResult TestMethod(int id)
然后尝试使用不同的 url 进行 ajax 调用:
$.ajax(
url: '/indices/TestMethod/1',
data: id,
type: 'POST',
success: function (data)
var tr = 123;
var yr = data;
//Do something
);
使用属性路由和 URL 中的参数值,我在 Fiddler 中看到首先发生了一个 POST 请求,它得到了 301 状态错误,但随后也发出了一个 GET 请求,它得到了 404 错误。
更新 3: 经过更多调查后,我充分缩小了问题定义的范围,因此打开一个新问题是有意义的,可以在这里找到: ASP MVC jQuery $.ajax POST request does not call controller method, but works in "fresh" MVC project
此问题似乎是由对此项目处于活动状态的内容安全策略设置引起的。
【问题讨论】:
您如何尝试联系此操作? 您确定请求是 POST 到动作,而不是其他动词吗?安装 Fiddler 并检查请求数据。 添加了一些额外的信息 - 据我所知,发送了一个 POST 请求,但由于我收到 404 错误,它从未到达控制器。 使用 Fiddler 查看实际发送的内容。您可能调用了错误的 URL - 您使用的是相对于根目录的 url,而不是当前页面。如果您的网站托管在例如http://someroot/somesubsite
,您的代码将调用http://someroot/indices/testMethod/
,而不是http://someroot/somesubsite/indices/testMethod
您可以使用@html.ActionLink 通过提供控制器和动作名称来生成目标ULR,从而避免URL 歧义
【参考方案1】:
尝试将param1
更改为id
,看看是否有效。这听起来可能很愚蠢,但实际上我在自己之前遇到过你的问题并且解决了问题。
我能想到的另一个问题是,在您的应用中,testMethod
的路径是带有大写字符的/Indices/TestMethod
。当您请求/indices/testMethod/
时,可能会发生一些重定向,从而导致GET
请求。
尝试更改 ajax 调用中的 url
或尝试添加 [Route()]
属性来设置路由名称。
【讨论】:
我遇到了类似的问题。更改参数没有任何区别。解决方法是在 url 中使用小写字母。【参考方案2】:您可能需要将FromBody
-属性添加到int param1
-参数,因为它是一个简单类型?请参阅here 了解更多信息。
否则,需要格式为 /indices/testMethod/param1
的路由(即参数必须在 URL 中,即使它是 POST 请求)。此路线可能未定义,即在您的global.asax.cs
中。例如,您可以尝试向/indices/testMethod/1
发出 POST 请求。只是尝试一下是否真的是路由问题?
如果您的路由确实存在问题,您可以使用Attribute Routing 为您的方法定义一个特定的路由。至少对于测试/开发而言,这样可以更轻松地查看/理解实际为您的方法定义的路由。
一些额外的问题可以缩小范围,它实际上可能是什么:
你dataGoesHere
-object 有什么格式?
工作的 POST 方法是什么样的?他们的参数是什么数据类型?引用类型还是值类型?
您注册了哪些路线(即在global.asax.cs
中)?
更新
我会尝试以下:
像这样定义控制器方法:
[HttpPost]
[Route("indices/TestMethod/")]
public ActionResult TestMethod([FromBody] int id)
像这样定义动作调用:
$.ajax(
url: '/indices/TestMethod/',
data: id, // alternatively try: id: id
type: 'POST',
success: function (data)
);
要么尝试将 id
作为简单值传递,要么尝试将其与具有 id
-property 的对象一起传递(参见上面的评论)。
【讨论】:
如果是这种情况,参数将为空(如果是引用,则为 null,如果为 int,则为 0)。 OP 根本无法调用 action。这与缺少参数无关 @PanagiotisKanavos:我们如何知道作者使用哪个 URL 尝试他提到的不同场景?我们怎么知道实际定义了哪些路线?如果param1
不是UrlParameter.Optional
,那么我认为在调用/indices/testMethod/
(没有其他参数)时该方法的路由不匹配。
@PzYon:你的回答是对的,[FromBody]是方法识别的重要组成部分。
路由机制不使用请求体来识别要调用的控制器方法,在参数声明中添加FromBody
可能只需要强制一种方式绑定参数参数必须来自何处是模棱两可的。不管参数是简单类型还是复杂类型,它都可能来自没有FromBody
的body。该属性只会影响被调用方法观察到的参数值,原则上不会影响方法定位能力。以上是关于用 [HttpPost] 装饰时 ASP MVC 控制器操作“未找到 404”错误的主要内容,如果未能解决你的问题,请参考以下文章
如何将模型作为参数传递给 ASP.NET MVC 中的 [HttpPost] ActionMethod?
asp.net mvc 用多个枚举装饰 [Authorize()]
HTTP 错误 405 | [HttpPost] ASP.NET MVC 核心 3.1