【问题标题】:multi submit button in one view一个视图中的多个提交按钮
【发布时间】:2014-07-07 00:43:53
【问题描述】:

我正在按照本教程构建具有多个提交按钮的表单: http://www.dotnet-tricks.com/Tutorial/mvc/cM1X161112-Handling-multiple-submit-buttons-on-the-same-form---MVC-Razor.html

但它没有工作...... 我有 2 个按钮:“登录”“发送”

我希望我的“发送”按钮通过电子邮件将密码发送给用户。 (在表“aspnetuser”中,我有属性“Email”)。

我该怎么做?

【问题讨论】:

  • 您能否在链接中发布您尝试实现该技术的代码?
  • 到目前为止你尝试过什么代码?请发布视图和控制器代码,如果可能的话,也请发布视图模型。

标签: c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


【解决方案1】:

听起来您正在尝试做两件事,让用户登录或找回密码。最佳做法是将它们分成两种不同的形式。

您的第一个表单将用于登录用户,并将用户名/密码发布到您的成员控制器上的登录操作:

@using (Html.BeginForm("Login", "Members"))
{
    <div>
        @Html.Label("username")
    </div>
    <div>
        @Html.Label("password")
    </div>
    <div>
        <input type="submit" value="Login" />
    </div>
}

您的第二个表单适用于忘记密码并将用户名发布到您的 Members 控制器上的 ForgotPassword 操作的人:

@using (Html.BeginForm("ForgotPassword", "Members"))
{
    <div>
        @Html.Label("username")
    </div>
    <div>
        <input type="submit" value="Reset Password" />
    </div>
}

附带说明,您不应以纯文本形式向用户发送密码。相反,您应该允许他们重置密码。这里有一个更好的解释为什么和如何:

http://www.asp.net/web-forms/tutorials/security/admin/recovering-and-changing-passwords-cs

祝你好运:)

【讨论】:

    【解决方案2】:

    正如@timothyclifford 所提到的,您正试图以一种形式做两件事。在某些情况下优先这样做,但对于 99% 的情况,链接到第二个表单是可行的方法。

    不久前,我确实实现了一个动作调用程序,它可以模拟您正在寻找的功能。它允许您在表单值中指定要执行的操作。

    它允许您使用有助于选择过程的属性标记控制器操作。

    我刚刚将一个工作示例上传到 github:https://github.com/xenolightning/asp-mvc-formaction

    FormActionInvoker.cs

    /// <summary>
    ///     Searches the controller for the correct action. Prioritizes FormAction attributed Actions first.
    ///     Then searches via Method Code
    /// </summary>
    public class FormActionActionInvoker : AsyncControllerActionInvoker
    {
        protected override ActionDescriptor FindAction(ControllerContext controllerContext,
            ControllerDescriptor controllerDescriptor, string actionName)
        {
            foreach (var mi in controllerDescriptor.ControllerType.GetMethods())
            {
                //Searches for the form action attribute first. And if it is present, then it looks
                //checks to see if the request is valid. This hpens BEFORE it checks the action name
                //which now means ActionName becomes obsolete
                var fa =
                    mi.GetCustomAttributes(false).FirstOrDefault(x => x is FormActionAttribute) as FormActionAttribute;
    
                if (fa == null)
                    continue;
    
                if (FormActionAttribute.GetAction(controllerContext) != null &&
                    fa.IsValidForRequest(controllerContext, mi))
                    return new ReflectedActionDescriptor(mi, actionName, controllerDescriptor);
            }
    
            ActionDescriptor ad = base.FindAction(controllerContext, controllerDescriptor, actionName);
            var rad = ad as ReflectedActionDescriptor;
    
            if (rad == null)
                return ad;
    
            //Here we have to check that the form action attibute isn't in required mode. If it is
            //and the form-action is null then we should return null
            var formA =
                rad.MethodInfo.GetCustomAttributes(false).FirstOrDefault(x => x is FormActionAttribute) as
                    FormActionAttribute;
    
            if (formA != null && FormActionAttribute.GetAction(controllerContext) == null &&
                formA.Mode == FormActionMode.Required)
                return null;
    
            return rad;
        }
    }
    

    FormActionAttribute.cs

    /// <summary>
    ///     When Required the action cannot be invoked unless the form has
    ///     the required form-action value
    /// </summary>
    public enum FormActionMode
    {
        Required,
        Normal
    }
    
    public class FormActionAttribute : ActionMethodSelectorAttribute
    {
        public const string HTTP_FORM_NAME = "form-action"; 
    
        public FormActionAttribute(params string[] values)
            : this(FormActionMode.Required, values)
        {
        }
    
        /// <summary>
        ///     Constructor to specify the FormActionMode
        /// </summary>
        /// <param name="mode">
        ///     Specify Normal to allow invocation of the action with out the matching form action. Defaults to
        ///     Required
        /// </param>
        /// <param name="values"></param>
        public FormActionAttribute(FormActionMode mode, params string[] values)
        {
            Values = values;
            Mode = mode;
        }
    
    
        public string[] Values
        {
            get;
            private set;
        }
    
        public FormActionMode Mode
        {
            get;
            private set;
        }
    
        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
        {
            string action = GetAction(controllerContext);
    
            if (string.IsNullOrEmpty(action))
                return true;
    
            return Values.Any(x => x.Equals(action, StringComparison.CurrentCultureIgnoreCase)) ||
                   methodInfo.Name.Equals(action, StringComparison.CurrentCultureIgnoreCase);
        }
    
        /// <summary>
        ///     Returns the form action from the current context. Returns null if there is no action
        /// </summary>
        /// <param name="controllerContext"></param>
        /// <returns>Null if there is no action</returns>
        internal static string GetAction(ControllerContext controllerContext)
        {
            string action = controllerContext.HttpContext.Request.Params[HTTP_FORM_NAME];
    
            if (string.IsNullOrEmpty(action))
                return null;
    
            //Stops errors on multiple value submissions
            //this will choose the first value in the form
            if (action.IndexOf(",") > -1)
                return action.Split(',')[0];
    
            return action;
        }
    }
    

    HomeController.cs

    public class HomeController : Controller
    {
    
        protected override IActionInvoker CreateActionInvoker()
        {
            return new FormActionActionInvoker();
        }
    
        public ActionResult Index()
        {
            return View();
        }
    
        [FormAction]
        public ActionResult Login(LoginModel model)
        {
            return View("Login", model);
        }
    
        [FormAction("Forgot")]
        public ActionResult DoesntMatterWhatThisIs(LoginModel model)
        {
            return View("Forgot", model);
        }
    
        [FormAction(FormActionMode.Normal)]
        public ActionResult Three(LoginModel model)
        {
            return View("Three", model);
        }
    }
    

    Index.cshtml

    <h2>A Multi Action Form:</h2>
    
    @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { @class = "form-horizontal" }))
    {
        <div class="form-group">
            <label for="@Html.IdFor(x => x.Username)" class="col-sm-2 control-label">Username</label>
            <div class="col-sm-10">
                @Html.TextBoxFor(x => x.Username, new { @class = "form-control" })
            </div>
        </div>
        <div class="form-group">
            <label for="@Html.IdFor(x => x.Password)" class="col-sm-2 control-label">Password</label>
            <div class="col-sm-10">
                @Html.PasswordFor(x => x.Password, new { @class = "form-control" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button class="btn btn-primary" name="form-action" value="Login">Login</button>
                <button class="btn btn-primary" name="form-action" value="Forgot">Forgot Password</button>
                <button class="btn btn-primary" name="form-action" value="Three">Do Three</button>
            </div>
        </div>
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 2013-04-16
      • 2011-03-20
      • 2015-10-04
      • 1970-01-01
      相关资源
      最近更新 更多