Setup:
I have designed a Wizard (based initially on Steve Sanderson's wizard in Pro ASP.NET MVC 2).
Essentially, the base wizard controller is declared as follows:
public abstract class WizardController<TModel> : Controller where TModel : class, IWizardModel, new()
{
// Loads-n-loadsa-code
}
To implement my wizard, therefore, I need to declare my Wizard controller as follows:
[WizardOptions(StartLabel="Edit >>")]
public partial class EditFeeEarnerController : WizardController<MyApp.Models.MySpecificWizardModel>
{
// small amounts of highly intuitive code
}
Where MyViewModel implements IWizardModel.
So far so good. The wizard works beautifully and I am right chuffed with it, so don't get hung up on that.
The issue follows:
Issue:
The only issue is that my Wizard uses partial views for each step, that get "stitched" together with a view (Wizard.cshtml).
Wizard.cshtml is ALWAYS the same for ANY wizard EXCEPT for the @model declaration at the top, in my example:
@model MyApp.Models.MySpecificWizardModel
As a result, in an app with 20 wizards, I have the very same file appearing 20 times.
Definitely not DRY.
Question:
I would like to put a file in ~/Views/Shared/Wizard.cshtml and use that for all my wizards. The reason I can't do that is because I only know in advance that my wizard viewmodels will inherit from IWizardModel.
And I can't do this:
@model IWizardModel
So what is the best way to do this, or is it just not possible?
I suppose I could have a base Wizard viewmodel that all my wizard viewmodels inherit from (instead of directly implementing IWizardModel).
Would this work?
EDIT (With the benefit of hindsight):
For the record, my problem was that I was misguided in thinking that using an interface as my model, ie, @model IWizardModel, wouldn't work. As Iain Galloway pointed out in his answer, it does and that solved my problem.
The reason I thought I couldn't use an interface as my model is that I did the following:
@model IWizardModel // MyNamespace.MySpecificWizardModel
The problem is the comment to the right (I commented out the old model).
For some reason, the comment generated an error (something to do with the ViewEngine). In my haste, I just presumed you couldn't use interfaces for the model.
As olde Will said: Great is thy power, oh delay.
See Iain Galloway's answer and my Addendum to it.
@Html.Action("MyAction", "MyController")?