2011-12-18 79 views
2

我正在使用http://afana.me/post/create-wizard-in-aspnet-mvc-3.aspx向导在ASP.NET MVC3和多HttpPost

它的伟大工程中描述的向导控制,但我需要有多个HttpPost相同的控制器内。在我的场景中,我需要在转到下一步之前添加到集合中。在该步骤的部分视图中。我有以下设置:

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

当我点击Add经验输入时,它被路由到

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

代替

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

} 

我究竟做错了什么?

+0

你不需要你的'[ActionName]'s。 – SLaks 2011-12-18 00:06:11

+0

我意识到问题不是[ActionName],但事实上我有一个Http.BeginForm()中的Http.BeginForm()。但问题依然存在。如何做一个邮政回来添加到收藏。 – jmogera 2011-12-18 00:10:50

+0

我没有回答这个问题;我指出了一个冗余。 – SLaks 2011-12-18 00:12:36

回答

1

这听起来像是你需要将你的CandidateViewModel分解成单独的ViewModel和你的大的Wizard视图到不同的视图中,这样每个步骤对于向导都有一个动作。

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

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

然后,当你想提高的UI行为,添加一些AJAX,也许使用的东西像jQuery UI选项卡,使其更像一个桌面应用程序的向导。

+0

乱七八糟后..我终于用这种方法,它工作得很好。没有花哨的jquery! – jmogera 2012-01-18 16:07:54

1

这听起来像你还是有嵌套形式。不要这样做,它不是有效的HTML。

你有2个选择这里,取决于你想要达到的目的。如果你想分开发布你的工作经历,那么把它们放在自己的@using(Html.BeginForm中,但不要将它们嵌套在外面。当用户点击添加体验按钮时,请完成您的工作,然后将新视图返回给用户。

如果你想同时发布所有的工作经验,然后把他们全部包装在一个@using(Html.BeginForm,不要把@using(Html.BeginForm)放在你的部分视图中。请参阅another question I answered here for more info on how to post a collection of items in a single HTTP POST

第二种方法就像你试图实现的一样,为此,你可能应该使用AJAX向你的集合添加多个工作体验,而不需要做一个完整的回发。提交集合中的所有工作经验给你的向导控制器,实现这样的功能并不难:

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 
1

你需要使用ActionMethodSelectorAttributeActionNameSelectorAttribute允许对行动增加新的属性来调用相应的按钮的不同作用点击 在View:

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

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

//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那么你不需要指定的索引操作ActionName属性,现在AddJobExperience_Index的行为与索引操作相同。