0

I've got problem how to design correctly flow for my controller witch will do some advanced things. I have to have multiple-step adding course in my site. It looks like this:

    public class CoursesController : Controller {
      [HttpGet]
      public ActionResult Create() //1 step - User fill some basic infos and send back forms to Save method
      {
       return View(model.GetNewInstanceOfCourse());
      }   
      [HttpPost]
      public ActionResult Save(NewCourse newCourse) //2 step - Datas are stored in session
      {
        string Token = Guid.NewGuid().ToString("D");
        Session.Add(Token, newCourse);
        return RedirectToAction("Subjects", new { Token = Token });
      }
      [HttpGet]
      public ActionResult Subjects(string Token) //2 step - Users fill which Subjects will be on the course, then send forms to Confirm method
      {
        return View(model.GetAvaliableSubjects(Token/*to place Token in View and let retrieve object from session*/);
      }
      [HttpPost]
      public ActionResult Confirm(Subjects subjects) //3 step - Users filled all required datas and now i want to store complete datas in database 
      {
        //(assume that Session[...] return Dictionaty<string, ... > instead of object
        if(!Session["stored-courses-from-first-step"].ContainsKey(subjects.RetrievedFromViewToken)
        {
          return RedirectToAction("Create");
        }
        model.AddNewCourse(Session["stored-courses-from-first-step"][subjects.RetrievedFromViewToken], subjects);
        return RedirectToAction("Index");
      }
    }

and it works perfectly... but i have to write adding new subjects for existing course so reuse step 2 in other part of my controller. I have to fill some different datas, then reuse adding subjects for this datas and then reuse function Confirm but instead of inserting some datas i want just update and insert some datas completed from user.

 ...
 public AddNewSubject(int CourseId)
 {
   ...
 }

In course preview i have button "Add new subjects", this should bring me to AddNewSubject Method and i don't know what to do next. I can't do in this method something like that:

   return RedirectToAction("Save", "Courses", new { newCourse = model.GetExistingCourseAnChangeItToNewCourseInstance(CourseId)})

i don't want to write specialized methods for this due to duplicating most of this code. I think it's possible to reorganize flow in my controller but i doesn't have good idea how to do that. Other problem is that i need to reuse method Confirm, one time it will insert some datas, other time it will update some datas. Maybe you will have some good tips for me.

Jason Evans
  • 28,906
  • 14
  • 90
  • 154
Puchacz
  • 1,987
  • 2
  • 24
  • 38
  • it may be very useful to check out this answer to a previous SO question which provides an alternative means to achieve this: http://stackoverflow.com/questions/6402628/multi-step-registration-process-issues-in-asp-net-mvc-splitted-viewmodels-sing/6403485#6403485 – jim tollan Nov 24 '13 at 14:00

2 Answers2

0

For existing courses, where you will be passing the course ID, there's nothing stopping you overloading the action method:

[HttpPost]
public ActionResult Save(int CourseId) //2 step - Datas are stored in session
{
    // Do whatever you need to do...
}

This way, you do not have to worry about doing anything clever when trying to reuse the step 2 code you posted. You simply have a separate method for dealing with existing courses.

Jason Evans
  • 28,906
  • 14
  • 90
  • 154
0

The cleanest solution is remove the real logic from the reusable actions, and put it in private methods.

In the method you decide what to do given some input params or something like that.

So, in your action you end up just calling the helper method. This helper methods can be private in the same controller... or if the amount of logic is large you can create a helper class to host that logic.

Romias
  • 13,783
  • 7
  • 56
  • 85