Jay
Jay

Reputation: 2703

How can I change the view at runtime using EditorFor() on List<T>

I have a base class

public class BaseQuestionBlock
{
        public string Name { get; set; }
        public string Description { get; set; }
        //more props
}

And I have several view models that inherit from this, for example:

public class DefaultQuestionBlock : BaseQuestionBlock
    {
        public string SomeProp{ get; set; }
    }

Finally I have a class that contains a List:

public class MyViewModel    {
        public List<BaseQuestionBlock> MyQbs{ get; set; }
        //More props
    }

I have a View where I render

@Html.EditorForModel(); //my model is MyViewModel

Inside the MyViewModel.cshtml i have the following:

@Html.EditorFor(m => m.MyQbs)

Everything displays properly using the views for each model. I have a custom model binder that correctly handles converting the posted qb's into their correct classes and I have a nicely populated view model on HttpPost.

I want to add modes to this process (e.g. New, Edit and Admin modes). My Model will stay the same but the view will change. I currently have 1 view per inherited question block. So, I have a DefaultQuestionBlock.cshtml and maybe a SpecialQuestionBlock.cshtml.

I would like to have an EditDefaultQuestionBlock.cshtml, NewDefaultQuestionBlock.cshtml, and a AdminDefaultQuestionBlock.cshtml.

Using the existing conventions in MVC is there a way to force what template to use?

Upvotes: 2

Views: 567

Answers (2)

Arwin
Arwin

Reputation: 1023

I am still finding my way around this as well, but right now I would use an @Html.Action that returns different partial views depending on the user's role/security privileges. If you generally always have three 'roles', for instance, you could use a naming convention that allows you to return a viewname that appends a code so you can return something like

return PartialView("_DefaultQuestionsBlock" + Mode);

Upvotes: 1

Chris Pratt
Chris Pratt

Reputation: 239270

There's not going to be a conventions-based way unless you go ahead and implement those view models for each "mode", which I agree seems like overkill. However, you can always just manually specify what template it should use. For example:

@Html.EditorForModel("~\Views\Shared\EditorTemplates\AdminDefaultQuestionBlock.cshtml")

Obviously, you can put the template wherever you like. I'm also not sure how much of the path is actually required there, so I went ahead and went safe and specified the whole thing. You could perhaps get away with as little as "AdminDefaultQuestionBlock" if it's in just the right location for Razor to be able to find it based on the context it has. You can play around with it.

Upvotes: 1

Related Questions