【问题标题】:Wizard in ASP.NET MVC3 and Multiple HttpPostASP.NET MVC3 和多个 HttpPost 中的向导
【发布时间】:2011-12-18 00:01:57
【问题描述】:

我正在使用http://afana.me/post/create-wizard-in-aspnet-mvc-3.aspx中描述的Wizard控件

效果很好,但我需要在同一个控制器中拥有多个 HttpPost。在我的场景中,我需要在进行下一步之前添加到集合中。在该步骤的局部视图中。我有以下设置:

@using (Html.BeginForm("AddJobExperience", "Candidate"))
{
   <input type="submit" value="Add Experience" />
}

当我按下添加体验输入时,它被路由到

[HttpPost, ActionName("Index")]
public ActionResult Index(CandidateViewModel viewModel)
{
}

而不是

[HttpPost, ActionName("AddJobExperience")]
public ActionResult AddJobExperience(CandidateViewModel col)
{

}

我做错了什么?

【问题讨论】:

  • 你不需要你的[ActionName]s。
  • 我意识到问题不在于 [ActionName],而是我在 Http.BeginForm() 中有一个 Http.BeginForm()。但问题仍然存在。如何做一个回帖以添加到收藏。
  • 我没有回答这个问题;我是在指出冗余。
  • 您是否将其用作主视图中的局部视图?
  • 是的,我是。所以一个索引有 Http.BeginForm() 并且每个步骤都是部分视图。而这个局部视图又有 Http.BeginForm() 了。

标签: asp.net-mvc-3 asp.net-mvc-routing


【解决方案1】:

听起来您需要将 CandidateViewModel 分解为单独的 ViewModel,将大的 Wizard View 分解为单独的 View,以便向导的每个步骤都有一个操作。

第一步他们添加了工作经验,因此有一个视图、视图模型和一个动作,第二步他们做其他任何事情,你也有一个单独的视图、视图模型和动作。等等等等

将您的 CandidateViewModel 分解为单独的 ViewModel 意味着您可以只关注该步骤所需的数据,并可以添加验证,然后当他们单击提交时,它将数据发布到下一步。

然后,当您想改进 UI 行为时,添加一些 AJAX,并可能使用 JQuery UI Tabs 之类的东西,使其行为更像桌面应用程序中的向导。

【讨论】:

  • 在搞砸之后..我终于采用了这种方法,它工作得很好。没有花哨的 jquery!
【解决方案2】:

听起来您仍然有嵌套表单。不要这样做,它不是有效的 HTML。

这里有 2 个选项,具体取决于您要实现的目标。如果您想一次单独发布一份工作经历,请将它们放在自己的@using(Html.BeginForms 中,但不要将它们嵌套在外部形式中。当用户单击“添加体验”按钮时,请针对该体验进行操作,然后将新视图返回给用户。

如果您想同时发布所有工作经历,请将所有工作经历包装在一个 @using(Html.BeginForm 中,并且不要将 @using(Html.BeginForm 放在您的部分视图中。请参阅 @987654321 @。

第二种方法听起来像是您想要实现的,为此,您可能应该使用 AJAX 将多种工作体验添加到您的集合中,而无需进行完整的回发。然后,您可以执行 1 个 HTTP POST 以将集合中的所有工作体验提交到您的向导控制器。实现这样的功能并不难:

Given I can see the Add Experience button
When I click the Add Experience button
Then I should see a new experience partial view with input fields
And I should enter data in these fields

When I click the Add Experience button a second time
Then I should see another new experience partial view with input fields
And I should enter data in these fields

When I click the Add Experience button a third time
Then I should see a third new experience partial view with input fields
And I should enter data in these fields

When I click the Next button in the wizard
Then my controller will receive data for all 3 experiences I submitted in a single form

【讨论】:

    【解决方案3】:

    您需要使用 ActionMethodSelectorAttributeActionNameSelectorAttribute 允许在操作上添加新属性以在按钮单击时调用不同的操作 在视图中:

    @using (Html.BeginForm())
    {
       <input type="submit" value="Add Experience" name="AddExperience" />
       <input type="submit" value="Add Experience" name="AddJobExperience" />
    }
    

    在扩展 ActionMethodSelectorAttribute 类的应用程序中添加新类 FormValueRequiredAttribute 以检查单击了哪个按钮

    //controller/FormValueRequiredAttribute.cs
    
    public class FormValueRequiredAttribute :  ActionMethodSelectorAttribute
        {
            public string ButtonName { get; set; }
    
            public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
            {
                var req = controllerContext.RequestContext.HttpContext.Request;
                return !string.IsNullOrEmpty(req.Form[this.ButtonName]);
            }
    
        }
    

    那么你应该在动作上添加这个属性来调用相应的动作

    在控制器中

    [HttpPost]
    [FormValueRequired(ButtonName = "AddExperience")]
    public ActionResult Index(CandidateViewModel viewModel)
    {
      return View();
    }
    
    [HttpPost]
    [ActionName("Index")]
    [FormValueRequired(ButtonName = "AddJobExperience")]
    public ActionResult AddJobExperience_Index(CandidateViewModel viewModel)
    {
      return View();
    }
    

    请注意,如果您在 Index.cshtml 中的 Html.BeginForm 方法,那么您不需要在 Index Action 上指定 ActionName 属性,现在 AddJobExperience_Index 的行为与 Index Action 相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-02
      • 2012-08-05
      • 2019-07-22
      • 2012-01-17
      • 2012-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多