在查看.NET MVC4 ActionNameSelectorAttribute多个按钮不工作 [英] .NET MVC4 ActionNameSelectorAttribute multiple buttons within View is not working

查看:191
本文介绍了在查看.NET MVC4 ActionNameSelectorAttribute多个按钮不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经看了很多帖子关于允许不同的看法,不同的按钮控制器动作。但是,我不能得到这个工作了。

I have read many posts about allowing different controller actions for different view-buttons. However, I cannot get this to work.

我使用的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;
    }
}

当我通过这个code步骤,我看到 methodInfo.Name 一个比较 actionName 的。怎么能这些不断相等时的整个目的是命名从控制器的作用不同的方法。

When I step through this code, 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.

什么是真或假的返回值实际上意味着作为的行为/功能?

What is the return value of true or false actually mean as to the behavior/functionality?

我应该以'行动'覆盖'fciContactUs行动?

Should I be overriding the 'fciContactUs' action with 'Action'?

控制器=HomeController的

The 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....} 
  }

视图(View名称是'fciContactUs)的形式启动:

The View (view name is '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和方法从来没有得到执行。

Further, this IsValidName method ALWAYS returns false and the methods NEVER get executed.

我担心没有在动作的名称不一致,视图名,控制器名,钮扣名称和 ActionNameSelectorAttribute 类覆盖。

I am concerned that there is an inconsistency in the action-name, the view-name, the controller-name, the button-names and the ActionNameSelectorAttribute class override.

我是新来的MVC,这整个事情已经让我扭了起来。

I am new to MVC and this whole thing has got me twisted up.

任何意见或协助将大大AP preciated。

Any comments or assistance will be greatly appreciated.

推荐答案

让我们先从 HttpParamActionAttribute 。这继承了 ActionNameSelectorAttribute 其中:

Let's start with the HttpParamActionAttribute. This inherits from ActionNameSelectorAttribute which:

重新presents影响操​​作方法的选择的属性。

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

所以,当应用到一个动作,并请求(GET或POST)进来时,此属性将被调用,看看是否能采取行动确实是正确的行动。

so, when applied to an action, and a request (get or post) comes in, this attribute will be called to see if that action is indeed the correct action.

它通过调用IsValidName确定此(略显混乱的方法,效果会更好'IsMatchingAction或类似)。 IsvalidName:

It determines this by calling IsValidName (slightly confusing method, would be better 'IsMatchingAction' or similar). IsvalidName:

确定操作名称是否在指定的控制器上下文有效。

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

使用的参数:

controllerContext:控制器方面

  actionName:动作
的名称
  MethodInfo的:有关操作方法的信息

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

,你可以得到通过该请求的请求和所有的值 controllerContext

taken from the blog post, you can get the request and all the values on that request via the controllerContext.

这将返回真正如果它匹配和如果不是我们要找的行动。

This returns true if it matches and false if it isn't the action we're looking for.

在此被击中:


  • actionName =从 BeginForm ,硬codeD操作名称为行动

  • 的MethodInfo =该属性应用于,如: TrySubmit 控制器动作(方法)

  • actionName = the action name from the BeginForm, hardcoded to "Action"
  • methodInfo = the controller-action (method) that the attribute is applied to, eg TrySubmit

因此​​,第一个检查:

So the first check:

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

仅仅是一个包罗万象的在你指定在你的 BeginForm ,这样它去请求的操作(即不行动比其他行动的东西的情况下)。

is just a catch-all in the case where you've specified something other than Action in your BeginForm so that it goes to the requested action (ie not "Action").

这是你的有无的第二次检查检查规定动作的 BeginForm

The second check checks that you have specified "Action" in the BeginForm

现在的聪明的一部分:

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

这将检查所有的要求参数,看看是否有相匹配的控制器的动作(方法)的参数。

this checks all the request parameters to see if there is a parameter that matches the controller-action (method).

当您单击提交按钮的提交按钮,名称在请求中传递参数

When you click a submit button, the name of that submit button is passed in the request parameters

所以,如果您有:

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

如果您点击提交,则:

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

如果您点击清除表单,然后

and if you click your "Clear Form", then

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

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

the actual value ("Submit"/"Clear Form") isn't needed, only that it's not null.

所以,code

request[methodInfo.Name] 

检查相匹配的电流控制器动作(方法)的名称,项目的是否存在等的请求参数例如:

checks the request parameters for the existance of an item which matches the current controller-action (method) name, eg:

[HttpParamAction]
public ActionResult DoClearForm() 
{


要回答你的第一个问题:


To answer your first question:

我看到一个methodInfo.Name比较actionName的。怎么能这些不断相等时的整个目的是命名从控制器的作用不同的方法。

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 没有指定动作和 BeginForm 的行动的覆盖不符合控制研究行动(方法)名称。

The first compare is an override for when the BeginForm doesn't specify Action and the BeginForm's action does match the controll-action (method) name.

所以,在你的情况下,没有他们不会平等的,不应该是 - 它的的最后的检查是相关的

So, in your scenario, no they won't be equal and shouldn't be - it's the last check that's relevant.

现在的问题是:

为什么不这样对你的工作?

why doesn't this work for you?

问题是,你的动作名称不匹配预期的动作名称,因为你有这样的:

The problem is that your action names don't match the expected action names, because you have this:

[ActionName("Action")]

所以 HttpParamAction 属性来查找您的控制器动作(方法),并说:用这一个,但随后MVC说,但我在寻找行动这不是行动让我给你的资源不能找到。我不是它这样做的原因100%,但如果你使用MVC5这是相同的路线(行动) - 它无法找到在已经行动与之匹配的是使用属性。

so the HttpParamAction attribute finds your controller-action (method) and says "use this one", but then MVC says, but I'm looking for "Action" and that's not "Action" so I'll give you "The resource cannot be found". I'm not 100% of the reason it's doing this, but it's the same if you use MVC5 Route("Action") - it can't find the action having already matched it using the attribute.

如果您删除 [ActionName(行动)] 那么所有的应该没问题。

If you remove [ActionName("Action")] then all should be ok.

替代:如果删除了前两个检查(!如果表单行动=控制器动作,如果形式的行动=行动),并只适用属性到您需要的方法(为什么的你在其他地方应用它?),那么它似乎很好地工作。

Alternative: if you remove the first two checks (if form action = controller action and if form action != "Action") and only apply the attribute to the methods you need (and why would you apply it elsewhere?), then it seems to work fine.

现在,我使用 [路线()] 并更改:

的形式为:

using (Html.BeginForm("", "", FormMethod.Post, ...

控制器:

[HttpParamAction]
[HttpPost]
[Route("")]
public ActionResult DoClearForm() 
{

(初始 [HTTPGET] 也有 [路线()]

和属性为:

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(清除表单,fciContractUS)和一点的CSS这样做更容易使它看起来像一个按钮。


As an alternative, it looks like your "ClearForm" button simply redirects to the page. You could do this more easily with a simple @Html.ActionLink("Clear Form", "fciContractUS") and a bit of css to make it look like a button.

您也将有一个问题,如果您有任何客户端验证(如必填项),你将无法提交以清除表单,直到他们有值。

You'll also have an issue if you have any client-side validation (eg required fields) as you won't be able to "submit" to clear the form until they have values.

这篇关于在查看.NET MVC4 ActionNameSelectorAttribute多个按钮不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆