Asp.net mvc 4 .NET MVC4 ActionNameSelectorAttribute视图中的多个按钮不工作
我读过很多关于允许不同视图按钮的不同控制器操作的帖子。然而,我无法让它工作 我使用从中获得的这个代码片段 当我逐步浏览这段代码时,我看到了Asp.net mvc 4 .NET MVC4 ActionNameSelectorAttribute视图中的多个按钮不工作,asp.net-mvc-4,button,razor,view,controller,Asp.net Mvc 4,Button,Razor,View,Controller,我读过很多关于允许不同视图按钮的不同控制器操作的帖子。然而,我无法让它工作 我使用从中获得的这个代码片段 当我逐步浏览这段代码时,我看到了actionName与methodInfo.Name的比较。当整个目的是命名不同于控制器操作的方法时,这些方法怎么可能相等呢 对于行为/功能而言,true或false的返回值实际上意味着什么 我是否应该用“操作”覆盖“fciContactUs”操作 控制器=“HomeController” 视图(视图名称为“fciContactUs”)表单开始: @using
actionName
与methodInfo.Name
的比较。当整个目的是命名不同于控制器操作的方法时,这些方法怎么可能相等呢
对于行为/功能而言,true或false的返回值实际上意味着什么
我是否应该用“操作”覆盖“fciContactUs”操作
控制器=“HomeController”
视图(视图名称为“fciContactUs”)表单开始:
@using (Html.BeginForm("Action", "Home")) {
查看按钮:
<input type="submit" name="TrySubmit" value="Submit" />
<input type="submit" name="DoClearForm" value="Clear Form" />
此外,这个IsValidName
方法总是返回false,并且这些方法永远不会执行
我担心操作名称、视图名称、控制器名称、按钮名称和ActionNameSelectorAttribute
类重写中存在不一致
我是新加入MVC的,这整件事让我很纠结
任何意见或帮助都将不胜感激。让我们从
HttpParamActionAttribute
开始。这继承自ActionNameSelectorAttribute
,其中:
表示影响操作方法选择的属性
因此,当应用于一个操作,并且有一个请求(get或post)传入时,将调用此属性以查看该操作是否确实是正确的操作
它通过调用IsValidName(稍微令人困惑的方法,最好是“IsMatchingAction”或类似方法)来确定这一点。IsvalidName:
确定操作名称在指定的控制器上下文中是否有效
带参数:
控制器上下文:控制器上下文actionName:操作的名称
methodInfo:有关操作方法的信息 摘自博客文章,您可以通过
controllerContext
获取请求和该请求上的所有值
如果匹配,则返回true
;如果不是我们要查找的操作,则返回false
当它被击中时:
- actionName=来自
的操作名称,硬编码为“操作”BeginForm
- methodInfo=应用属性的控制器操作(方法),例如
TrySubmit
if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
return true;
如果您在BeginForm
中指定了除操作之外的其他内容,那么它将转到请求的操作(即不是“操作”),那么它只是一个总括
第二项检查检查您是否在BeginForm
现在是“聪明”部分:
这将检查所有请求
参数,以查看是否有与控制器操作(方法)匹配的参数
单击提交
按钮时,该提交按钮的名称
将在请求参数中传递
因此,如果你有:
<input type="submit" name="TrySubmit" value="Submit" />
<input type="submit" name="DoClearForm" value="Clear Form" />
如果你点击“清除表单”,那么
实际值(“Submit”/“Clear Form”)是不需要的,只是它不为空
那么代码呢
request[methodInfo.Name]
检查请求参数是否存在与当前控制器操作(方法)名称匹配的项,例如:
[HttpParamAction]
public ActionResult DoClearForm()
{
要回答您的第一个问题: 我看到actionName与methodInfo.Name的比较。当整个目的是命名不同于控制器操作的方法时,这些方法怎么可能相等呢 第一个比较是当
BeginForm
未指定操作且BeginForm
的操作与控制操作(方法)名称匹配时的覆盖
因此,在您的场景中,不,它们不相等,也不应该相等-这是最后一次相关检查
现在的问题是: 为什么这不适合你 问题是您的操作名称与预期的操作名称不匹配,因为您有以下情况:
[ActionName("Action")]
因此,HttpParamAction
属性找到您的控制器操作(方法)并说“使用这个”,但MVC说,但我在寻找“操作”,而不是“操作”,所以我会给您“找不到资源”。我不是100%的原因,但如果使用MVC5Route(“Action”)
,它无法找到已经使用属性匹配的操作
如果删除[ActionName(“Action”)]
,则一切都应该正常
备选方案:如果删除前两个检查(如果表单操作=控制器操作,如果表单操作!=“操作”),并且只将属性应用于所需的方法(为什么要在其他地方应用它?),那么它似乎可以正常工作 现在,我正在使用
[Route(“”)]
并更改了:
将表格发送至:
using (Html.BeginForm("", "", FormMethod.Post, ...
控制员应:
[HttpParamAction]
[HttpPost]
[Route("")]
public ActionResult DoClearForm()
{
(初始的[HttpGet]
还有[Route(“”)
)
属性为:
public class HttpParamActionAttribute : ActionNameSelectorAttribute
{
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
var request = controllerContext.RequestContext.HttpContext.Request;
return request[methodInfo.Name] != null;
}
}
另一种选择是,您的“ClearForm”按钮看起来只是重定向到页面。您可以通过一个简单的
@Html.ActionLink(“Clear Form”,“fciContractUS”)
和一点css使其看起来像一个按钮,更容易做到这一点
如果您有任何客户端验证(如必填字段),您也会遇到问题,因为在表单有值之前,您将无法“提交”以清除表单
[HttpParamAction]
public ActionResult DoClearForm()
{
[ActionName("Action")]
using (Html.BeginForm("", "", FormMethod.Post, ...
[HttpParamAction]
[HttpPost]
[Route("")]
public ActionResult DoClearForm()
{
public class HttpParamActionAttribute : ActionNameSelectorAttribute
{
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
var request = controllerContext.RequestContext.HttpContext.Request;
return request[methodInfo.Name] != null;
}
}