gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 01:15:44 25 4
gpt4 key购买 nike

我已经阅读了许多关于允许不同 View 按钮的不同 Controller 操作的帖子。但是,我无法让它发挥作用。

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

当我逐步执行此代码时,我看到 actionNamemethodInfo.Name 的比较。当整个目的是命名与 Controller 操作不同的方法时,这些怎么可能相等。

true 或 false 的返回值对于行为/功能实际上意味着什么?

我应该用“Action”覆盖“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....}
}

View ( View 名称是“fciContactUs”)表单开始:
@using (Html.BeginForm("Action", "Home"))  {

View 按钮:
<input type="submit" name="TrySubmit" value="Submit" />
<input type="submit" name="DoClearForm" value="Clear Form" />

此外,这个 IsValidName 方法总是返回 false 并且这些方法永远不会被执行。

我担心操作名称、 View 名称、 Controller 名称、按钮名称和 ActionNameSelectorAttribute 类覆盖不一致。

我是 MVC 的新手,这整件事让我感到困惑。

任何意见或帮助将不胜感激。

最佳答案

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

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



所以,当应用于一个 Action ,并且一个请求(get 或 post)进来时,这个属性将被调用以查看该 Action 是否确实是正确的 Action 。

它通过调用 IsValidName(有点令人困惑的方法,最好是“IsMatchingAction”或类似方法)来确定这一点。有效名称:

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 名称,硬编码为“ Action ”
  • methodInfo = 应用属性的 Controller Action (方法),例如 TrySubmit

  • 所以第一次检查:
    if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
    return true;

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

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

    现在是“聪明”的部分:
    var request = controllerContext.RequestContext.HttpContext.Request;
    return request[methodInfo.Name] != null;

    这将检查所有 request 参数以查看是否存在与 Controller 操作(方法)匹配的参数。

    当你点击一个 submit 按钮时,那个提交按钮的 name 被传入请求参数

    所以如果你有:
    <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] 

    检查请求参数是否存在与当前 Controller 操作(方法)名称匹配的项目,例如:
    [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 的 Action 与控制 Action (方法)名称匹配时的覆盖。

    因此,在您的场景中,不,它们不会相等,也不应该相等 - 这是相关的最后一次检查。

    现在的问题是:

    why doesn't this work for you?



    问题是您的操作名称与预期的操作名称不匹配,因为您有:
    [ActionName("Action")]

    所以 HttpParamAction 属性找到你的 Controller Action (方法)并说“使用这个”,但随后 MVC 说,但我正在寻找“ Action ”而不是“ Action ”,所以我会给你“资源不能被发现”。我不是 100% 这样做的原因,但是如果您使用 MVC5 Route("Action") 也是一样的 - 它找不到已经使用属性匹配它的操作。

    如果你删除 [ActionName("Action")] 那么一切都应该没问题。

    替代 :如果您删除前两个检查(如果表单操作 = Controller 操作,如果表单操作 != "Action")并且只将属性应用于您需要的方法(以及为什么要在其他地方应用它?)它似乎工作正常。

    现在,我正在使用 [Route("")] 并进行了更改:

    表格:
    using (Html.BeginForm("", "", FormMethod.Post, ...

    Controller :
    [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 更轻松地完成此操作,使其看起来像一个按钮。

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

    关于asp.net-mvc-4 - .NET MVC4 ActionNameSelectorAttribute View 中的多个按钮不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30970159/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com