ASP.NET MVC Dynamic Views

783 views Asked by At

I Posted the background to this question a few days ago.. but the answer is yet incomplete, so re-Posting with a summary.

I'm developing a MVC 3 Razor Web App, in which details of multiple categories of objects are stored. (Vehicles, Houses, Instruments etc) . All the objects share some common data (Title, Description etc) And some details which are specific to the category in which it belongs to. The Category list is expected to grow and in view of reducing maintainability we hope to reuse the same Add Object wizard . The wizard is based on the following implementation.

http://afana.me/post/create-wizard-in-aspnet-mvc-3.aspx

In the Multiple step wizard process , the final step allows the user to enter the category specific details (Model, Make, VIN etc for a Vehicle). The view page is bound to the "AssetView" Model, which is defined as follows

public class AssetView
{
    [Required]      
    public string Title { get; set;  }

    [Required]
    public string Description { get; set;}

    public SpecificAsset AssetDetails { get; set; }
}

the AssetDetails property will be dynamically changed at runtime according to the category type that is selected at a previous stage. the view looks like this

@model AssetView
....
<div class="wizard-step">
  ...
 </div>
<div class="wizard-step">
  ...
 </div>
<div class="wizard-step">
  @Html.EditorFor(model => model.AssetDetails)
 </div>

in the controller, based on category selection . i intialize assetdetails as follows

_thisAsset.AssetDetails = new MotorAsset();

I then override the views with type specific Editor templates.

The wizard works fine, but At the Save step in the controller the "AssetDetails" property has no values and it is shown to be of type "SpecificAsset" which is the base type. i'm unable to cast it to the specific type as well. However the formsCollection shows all values, the "AssetDetails" specific properties like "Transmission", "Make" are in the forms collection prefixed by "AssetDetails_" .

Keeping in mind that i need to handle over 20 types of specific categories (Motor, House etc) at the controller save step, how can i do this without some kind of hack?

2

There are 2 answers

1
Mikael Eliasson On BEST ANSWER

If you know the type of the AssetDetails you could do it like this:

  1. Take the AssetView as parameter to the action(binds the common properties)
  2. Create a new instance of the specific AssetDetails(for example CarDetails)
  3. Use one of the overloads of TryUpdateModel to bind the values. There are some overloads that let you specify prefix so it should always work
  4. Add this object to the AssetView.SpecificAsset

You need some way to know the specific type. But I guess you would have a variable that tracks the type so you could save it properly later anyway. If you don't it would be easy to add. Remember that it needs to be AssetView as AssetDetails are not being bound though.

If you need validation there is a TryValidateModel you could try too.

0
frennky On

As I understood, number of models will grow and you want to reuse action and view for all models. One option I see is to make a custom ModelBinder. You would examine FormCollection and than create a specific asset model.

The problem with your solution is that SpecificAsset has no properties, so default model binder doesn't bind any of fields to it.