asp.net-mvc-4 – .NET MVC4 ActionNameSelectorAttribute View中的多个按钮不起作用

前端之家收集整理的这篇文章主要介绍了asp.net-mvc-4 – .NET MVC4 ActionNameSelectorAttribute View中的多个按钮不起作用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经阅读了许多关于允许不同视图按钮的不同控制器操作的帖子.但是,我不能让这个工作.

我使用从http://blog.ashmind.com/2010/03/15/multiple-submit-buttons-with-asp-net-mvc-final-solution/获得的代码片段.

public class HttpParamActionAttribute : ActionNameSelectorAttribute 
{
    public override bool IsValidName(ControllerContext controllerContext,string actionName,MethodInfo methodInfo) 
    {
        if (actionName.Equals(methodInfo.Name,StringComparison.InvariantCultureIgnoreCase))
            return true;

        if (!actionName.Equals("Action",StringComparison.InvariantCultureIgnoreCase))
            return false;

        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
}

当我单步执行此代码时,我会看到actionName与methodInfo.Name的比较.当整个目的是将方法命名为与控制器的动作不同时,这些EVER如何相等.

对于行为/功能,真或假的返回值实际上是什么意思?

我应该用’动作’覆盖’fciContactUs’动作吗?

Controller =“HomeController”

[HttpParamAction]
  [ActionName("Action")]
  [AcceptVerbs(HttpVerbs.Post)]
  [ValidateInput(false)]
  public ActionResult DoClearForm(fciContactUs p_oRecord)
  {
     return RedirectToAction("fciContactUs");
  }

  [HttpParamAction]
  [ActionName("Action")]
  [AcceptVerbs(HttpVerbs.Post)]
  public ActionResult TrySubmit(fciContactUs p_oRecord)
  {
     // This must be the Submit command.
     if (ModelState.IsValid)
     {  ...etc....} 
  }

表单视图(视图名称为’fciContactUs’)form-start:

@using (Html.BeginForm("Action","Home"))  {

视图按钮:

<input type="submit" name="TrySubmit" value="Submit" />
<input type="submit" name="DoClearForm" value="Clear Form" />

此外,此IsValidName方法始终返回false并且方法永远不会被执行.

我担心action-name,view-name,controller-name,button-names和ActionNameSelectorAttribute类覆盖中存在不一致.

我是MVC的新手,整个事情让我扭曲了.

任何评论或帮助将不胜感激.

解决方法

让我们从HttpParamActionAttribute开始.这继承自ActionNameSelectorAttribute,其中:

Represents an attribute that affects the selection of an action method.

因此,当应用于某个操作,并且请求(获取或发布)进入时,将调用属性以查看该操作是否确实是正确的操作.

它通过调用IsValidName来确定这一点(稍微有些混乱的方法,会更好’IsMatchingAction’或类似). IsvalidName:

Determines whether the action name is valid in the specified controller context.

带参数:

controllerContext: The controller context
actionName: The name of the action
methodInfo: Information about the action method

博客文章获取,您可以通过controllerContext获取请求和该请求的所有值.

如果匹配则返回true,如果不是我们正在寻找的动作则返回false.

当它被击中时:

> actionName = BeginForm中的操作名称,硬编码为“Action”
> methodInfo =应用该属性的controller-action(方法),例如TrySubmit

所以第一次检查:

if (actionName.Equals(methodInfo.Name,StringComparison.InvariantCultureIgnoreCase))
    return true;

在您的BeginForm中指定了除Action之外的其他内容以便它转到请求的操作(即不是“Action”)的情况下,这只是一个包罗万象的事情.

第二次检查检查您是否在BeginForm中指定了“Action”

现在是“聪明”的部分:

var request = controllerContext.RequestContext.HttpContext.Request;
return request[methodInfo.Name] != null;

这将检查所有请求参数,以查看是否存在与controller-action(方法)匹配的参数.

单击提交按钮时,将在请求参数中传递该提交按钮的名称

所以如果你有:

<input type="submit" name="TrySubmit" value="Submit" />
<input type="submit" name="DoClearForm" value="Clear Form" />

如果你点击“提交”,那么:

HttpContext.Request["TrySubmit"] == "Submit"
HttpContext.Request["DoClearForm"] == null

如果你点击“清除表格”,那么

HttpContext.Request["TrySubmit"] == null
HttpContext.Request["DoClearForm"] == "Clear Form"`

不需要实际值(“提交”/“清除表单”),只是它不为空.

所以代码

request[methodInfo.Name]

检查请求参数是否存在与当前控制器 – 动作(方法)名称匹配的项目,例如:

[HttpParamAction]
public ActionResult DoClearForm() 
{

回答你的第一个问题:

I see a compare of actionName with methodInfo.Name. How can these EVER be equal when the whole purpose is to name the method different from the controller’s action.

第一个比较是当BeginForm未指定Action并且BeginForm的操作与controll-action(方法)名称匹配时的覆盖.

所以,在你的场景中,他们不会是平等的,也不应该是 – 这是最后一次相关的检查.

现在的问题是:

why doesn’t this work for you?

问题是您的操作名称与预期的操作名称不匹配,因为您有:

[ActionName("Action")]

所以HttpParamAction属性找到你的控制器动作(方法),并说“使用这一个”,但随后MVC说,但我正在寻找“动作”,那不是“动作”所以我会给你“资源不能被发现”.我不是100%这样做的原因,但是如果你使用MVC5 Route(“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,MethodInfo methodInfo) 
    {
        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
}

作为替代方案,看起来您的“ClearForm”按钮只是重定向页面.您可以使用简单的@ Html.ActionLink(“Clear Form”,“fciContractUS”)和一些css使其看起来像一个按钮,从而更轻松地完成此操作.

如果您有任何客户端验证(例如必填字段),您也会遇到问题,因为在它们有值之前您无法“提交”清除表单.

原文链接:https://www.f2er.com/aspnet/251557.html

猜你在找的asp.Net相关文章