MetaGuru
MetaGuru

Reputation: 43813

When to use strongly typed views?

I am working on an MVC app and I am wondering in what situation it is best to use a strongly typed view and when not... I guess this is more of a best practice question. I am making an ecommerce app and there is a table for orders, products, etc. The part I was working on that brought me to this question was my add a new product page for the admins to put more store items in. Any tips about when to know to use strongly typed view will be great help.

I already searched for related questions and nothing popped out in the first 3 pages or so, but if you know of a post please direct me.

Thanks.

Upvotes: 5

Views: 1212

Answers (6)

John Gietzen
John Gietzen

Reputation: 49544

Any time you need to show data (on any particular object or collection of objects) on the view, use a strongly typed view.

If your view is purely informational, you may be able to use the ModelState to pass small bits of information (eg: Success/Error pages, Not Authorized Messages, and etc.)

In my applications, I have EVERY view strongly typed, so that I can easily pass user login information to the Master Page. That is, all of my views are strongly typed, templated and constrained to a base class that contains the Site Configuration and the User Login info.

Because of that, I can do this:

public class MyBaseMasterPage : ViewMasterPage<MyBaseModel>
{
    public string CurrentTheme
    {
        get
        {
            if (this.Model.CurrentUser != null)
                return this.Model.CurrentUser.Theme;

            else return this.Model.Config.DefaultTheme;
        }
    }

    public User CurrentUser { get { return this.Model.CurrentUser; } }

    public ConfigurationRepository Config { get { return this.Model.Config; } }
}

Note that, since the Master Page is themed based on ONLY what is populated in the model, the View itself will never trigger a hit to the database/cache.

MyBaseModel is configured like so:

public class MyBaseModel
{
    private MyBaseModel() { }

    public MyBaseModel(MyBaseController controller)
    {
        this.CurrentUser = controller.CurrentUser;
        this.Config = controller.Config;
    }

    public User CurrentUser { get; private set; }

    public ConfigurationRepository Config { get; private set; }
}

The private constructor forces all subclasses of my model to initialize the model with the soruce controller.

The controller base class pulls the user out of session and the Config out of cache.

That way, no matter what, all of my views have access to the user and config data, without ever generating a hit to the DB.

Now, in MyBaseController:

public class LanLordzBaseController : Controller
{
    [Obsolete]
    protected new ViewResult View(string viewName, object model)
    {
        if (model == null)
        {
            throw new ArgumentNullException("model");
        }

        if (!(model is MyBaseModel))
        {
            throw new ArgumentException("The model you passed is not a valid model.", "model");
        }

        return base.View(viewName, model);
    }

    protected ViewResult View(string viewName, MyBaseModelmodel)
    {
        if (model == null)
        {
            throw new ArgumentNullException("model");
        }

        return base.View(viewName, (object)model);
    }

    public ConfigurationRepository Config { get { ... } }

    public User CurrentUser { get { ... } }
}

This helped me find all of my controllers that were returning views that weren't inherited from the proper base class.

Upvotes: 5

mxmissile
mxmissile

Reputation: 11673

Always. I would go further and use strongly typed controls and HtmlHelper actions also. Most are available in the MvcContrib library.

Upvotes: 1

Wyatt Barnett
Wyatt Barnett

Reputation: 15673

If there is data involved, there should be a strongly typed view. Period.

Upvotes: 3

Lazarus
Lazarus

Reputation: 43074

Although I'm repeating what others have eloquently stated I think there is one more point to raise. The View is part of the Model, View, Controller concept and as such is there to present the Model in a visual way to the user. Given that it is, in essence, a representation of the Model it makes sense for it to be strongly typed.

I only ever use ModelState or TempState for passing small pieces of data, like outcome messages from activities like add, delete, etc. Any time I find tempted to use State to pass collections that are unrelated to the View-type then I refactor that functionality into a partial view and present that through a separate controller action.

In my code related types are generally referenced hierarchically from the base type to which the view is strongly-typed, and so are accessible within the View where necessary.

Upvotes: 0

Daniel Elliott
Daniel Elliott

Reputation: 22857

I use strongly typed views whenver I can so I can get away from all the casts of various bits of ViewData within the view.

I create my own strongly typed views any time I need information from more than one source for the view.

For example in my Checkout, I require an order but also the user's prefences for price display; so I created CheckoutViewModel which has an Order and PriceDisplay property.

Hope that helps,

Dan

Upvotes: 2

Robban
Robban

Reputation: 6802

A strongly typed view is best used when you modify an instance of that type in the view.

For example when you edit or create a Product in a view it would definitely be adviceable to have a strongly typed view for the product class.

If you are only displaying text or images without actually having a connection to anything in the underlying databaselayers it would probably be easier to go without a strongly typed view.

This will all come rather naturally as you work more with MVC in my experience.

Upvotes: 0

Related Questions