0

my current problem includes three classes let's say A, B and C. Class A includes one property of an object of class B and one of class C, a string in this case. the user should create a new object of type A in the first step without these two properties (only the other properties are asked). An incomplete object of type A (let's call it a) should be built and in the next step the user shall decide whether he wants to match this object to an existing B or a new one. After this decision, the needed property is added to a and in the third step, the second property will be added in the same way and to finish it, the object a will be saved in the database.

My current attempt looks like this:

    public ActionResult Create()
    {
        return View();
    }

    //
    // POST: /A/Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(A a)
    {
        if (ModelState.IsValid)
        {
            return RedirectToAction("ViewForB", new { a = a});
        }
        return View(a);
    }
    public ActionResult ViewForB(A a)
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult ViewForB(B b, A a)
    {
        if (ModelState.IsValid)
        {
            bDb.Bs.Add(b);
            bDb.SaveChanges();
            a.propertyForB = b.title;
            return RedirectToAction("ViewForC", new {a = a});
        }
        return View(b);
    }

    public ActionResult ViewForC(A a)
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult ViewForC(C c, A a)
    {
        if (ModelState.IsValid)
        {
            cDb.Cs.Add(c);
            cDb.SaveChanges();
            a.propertyForC = c.title;
            aDb.As.Add(a);
            aDb.SaveChanges();
            return RedirectToAction("Index/");
        }
        return View();
    }

As you can see I tried to pass an A object to every next view but when submitting in ViewForB this won't work, because I don't know how to pass it in this case. But in ViewForB objects of type B will also be built, therefore I decided to make it in this way to verify if the inputs for B are correct or not like in the create method.

Do you know how to pass an object of type A to the last view, to complete and safe it there?

Thank you very much, any answer would be helpful.

Underfaker
  • 97
  • 2
  • 12

1 Answers1

1

There's no simple way to "pass" an arbitrary object from one view to another like this. When you return a RedirectResult you are returning an instruction to the browser to send a fresh request to the next URL - you can include simple query string parameters in this but there is no convention for serializing an arbitrary object to a set of query string parameters.

You have various options:

  1. Store the information in a cookie and retrieve it in each action.
  2. Return views directly from your POST actions, include hidden fields for fields that have already been populated and gradually build up a complete model.
  3. Use Session or some other server-side storage mechanism (e.g. a secondary database) to save progress.

You can also pass individual properties in the redirect instead of an entire model (you can still bind back to a model in the next action). This could be used either to pass keys for a model stored in a cookie or in Session or - if you only have a few properties that you need - to just pass them all individually:

return RedirectToAction("ViewForC",
    new { Something = A.SomeProperty, SomethingElse = A.AnotherProperty });
Ant P
  • 24,820
  • 5
  • 68
  • 105
  • Thank you for your answer. I also found that option but I'm not sure how to use these hidden fields. ViewForB is still the same but I added this one for each property of A: I'm not sure how to set the value of the hidden field and after submitting, how to get it in the post method from ViewForB. – Underfaker May 21 '15 at 20:01
  • It tried for example: [HttpPost] public ActionResult ViewForB(B b) { if (ModelState.IsValid) { string title = titleField.Value; cDb.Bs.Add(b); cDb.SaveChanges(); return RedirectToAction("ViewForC", new { varTitle = title }); } return View(); } But it says that titleField is unknown in the context. – Underfaker May 21 '15 at 20:02
  • 1
    What is `titleField`? What is `varTitle`? These things don't appear to exist. Not sure what you're trying to do there. It sounds like you're confused on a few different fronts and you need to do some Googling and reading up on how model binding works. – Ant P May 21 '15 at 20:03
  • Have a look at my comment, titleField is a hiddenField, it is an example for a property of an object of type A. I didn't want to wrote all the properties I chose one for example. varTitle is the name of a variable, it is an example for a property of an object of Type A. In the controller-method for ViewForC I could write: public ActionResult ViewForC(string varTitle) { ... } . What I'm trying to do: I try to place a hidden field for one property of a, it's name should be "titleField". After submitting, I want to get the input of titleField to pass it to the next view. – Underfaker May 21 '15 at 20:22