views:

46

answers:

2

Hi,

I am using ASP.NET MVC. My requirement is to build a complex object (an object made of other object) through a step-by-step procedure like in a wizard.

Every dependent object shall be build on it's step and shall be validated in it's step. For example

public class ComplexObjectModel {
    public Object1 MyObject1 { get; set; }
    public Object2 MyObject1 { get; set; }
    public Object3 MyObject1 { get; set; }
}

As there is no built-in facility for a wizard I have decided to create 3 model classes and 3 strong typed partial views binded to these models.

On every step of my pseudo wizard I validate the dependent model object and set the property of the complex object to its reference.

I was thinking to save the complex object inside the ViewData/TempData in the following way

In the controller action

[HttpPost]
public ActionResult MyAction1() {
    ComplexObjectModel com = (ComplexObjectModel)ViewData["ComplexObjectModel"];
    com.MyObject1 = new Object1();
    ViewData["ComplexObjectModel"] = com;
    return PartialView( "MyAction2", com.Object1 );
}

and in the View

<% using (Html.BeginForm()) { %>
    <%= Html.Hidden("ComplexObjectModel", ViewData["ComplexObjectModel"]) %>

    ... view fields for Object1, Object n ....
<% } %>

But doing this way the object is not passed back-and-forth between the view and the controller and I have experienced that is null when it comes back from the view to the next action.

Is there a way to support this requirement?

thanks for helping

+1  A: 

There are a couple of ways I might tackle this.

First; I might decide to store all this in the session object. I am assuming here that the models are quite large and so I wouldn't want them stored on the view and passed back each time I go to the next page.

Second; I might store them in the database and if the wizard didn't complete then delete them as part of a background process.

The one thing I wouldn't do is pass the complex object to each view. The view should really need to know anything about any other view in a restful world and so I'd be inclined not to do it.

Of course that does mean you need to decide a storage place for the data. If I had a Large objcect then I'd choose the database and if was fairly small then I'd choose the session object.

As you have already found, having all the data for each object in each view can be problematic.

However, if you are determined to do this the View way then here is what I'd do;

  1. Create a partial view which deals only with each object in the complex model.
  2. On each view, include all three, or more, of the partial views.
  3. For each partial view which is not an active participant in the view, place it within a div that is hidden.

At least then when you change a property, or add one, you simply set it in the partial view once and not three times. Also if there is an error, you can unhide the divs and see if the data is coming in.

Also each field should then have the id of ModelName.Property so that the controller knows where the property is.

<%= Html.TextBox("MyObject1.MyProperty1", value) %>

Then in the controller you simply do, and this off the cuff;

[HttpPost]
public ActionResult MyAction1(ComplexObjectModel complexModel) {
griegs
it was not mandatory to go the View way... I went for the Session ;)
Lorenzo
A: 

You could take a look at MVC Futures Html.Serialize helper method which allows you to keep state into a hidden field between the controller actions in a similar way classic WebForms does it.

Darin Dimitrov
Sounds interesting...
Lorenzo