Мастер в ASP.NET MVC3 и нескольких HttpPost - PullRequest
2 голосов
/ 18 декабря 2011

Я использую элемент управления Wizard, описанный в http://afana.me/post/create-wizard-in-aspnet-mvc-3.aspx

Он отлично работает, но мне нужно иметь несколько 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)
{

}

Что такоеЯ делаю не так?

Ответы [ 3 ]

1 голос
/ 19 декабря 2011

Звучит так, как будто вам нужно разбить вашу CandidateViewModel на отдельные ViewModel и ваш большой Wizard View на отдельные Views, чтобы по одному на каждое действие для каждого шага мастера.

Шаг первый: они добавляют заданиеопыт, поэтому имейте представление, модель представления и действие для этого, на втором шаге они делают все остальное, и у вас также есть отдельное представление, модель представления и действие для этого.и т. д.

Разбиение вашей CandidateViewModel на отдельные ViewModel будет означать, что вы можете просто сосредоточиться на данных, необходимых для этого шага, и можете добавить проверку, а затем, когда они нажимают кнопку «Отправить», она отправляет данные на следующий шаг.step.

Затем, когда вы захотите улучшить поведение пользовательского интерфейса, добавьте AJAX и, возможно, используйте что-то вроде вкладок пользовательского интерфейса JQuery, чтобы сделать его более похожим на мастер в настольном приложении.

1 голос
/ 14 сентября 2012

вам необходимо использовать ActionMethodSelectorAttribute или ActionNameSelectorAttribute , которые позволяют добавить новый атрибут в действии для вызова другого действия при нажатии соответствующей кнопки в представлении:

@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();
}

Обратите внимание, что если ваш метод Html.BeginForm в Index.cshtml, то вам не нужно указывать атрибут ActionName для Index Action, теперь AddJobExperience_Index действует так же, как Index Action.

1 голос
/ 18 декабря 2011

Похоже, у вас все еще есть вложенные формы. Не делайте этого, это не правильный HTML.

У вас есть 2 варианта, в зависимости от того, чего вы пытаетесь достичь. Если вы хотите опубликовать свой опыт работы по одному, то поместите их в свои @using(Html.BeginForm с, но не вкладывайте их во внешнюю форму. Когда пользователь нажимает кнопку «Добавить опыт», выполняйте эту работу, а затем возвращайте пользователю новый вид.

Если вы хотите опубликовать все задания одновременно, оберните их все в один @using (Html.BeginForm) и не помещайте @using (Html.BeginForm в частичные представления. См. другой вопрос, на который я ответил здесь для получения дополнительной информации о том, как разместить коллекцию элементов в одном HTTP POST .

Второй метод - это то, что, по вашему мнению, вы пытаетесь достичь, и для этого вам, вероятно, следует использовать 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
...