Archive

Posts Tagged ‘Strongly Typed’

MVC – Strongly Typed Global ViewData

June 2nd, 2009 admin 2 comments

Most MVC stuff I have been doing has been quite basic and the knowledge gleaned off many blog sites ( thanks to you all :-) )I’m not a prolific blogger – too busy!!!, I’ll only blog when I have something to useful to share that isn’t easy to find.

I was looking for a way to provide ViewData at the Model level so that I could have some parameters available after every action that were strongly typed and injected into the ActionResult instead of ViewData["MyData"]. I want to use Model.MyData

I had a good search about but nothing definitive so I cam up with this.

The Base Controller Class.

It’s always a good idea to have you own base controller that is inherited from your other controllers. Here we are using it for storing Global Settings/Properties or any helper methods etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Web.Mvc;
 
namespace GlobalViewData.Controllers
{
 
    /// <summary>
    /// Base data container for ViewData Models
    /// </summary>
    public abstract class BaseFormViewModel
    {
        public string MyData { get; set; }
    }
 
    /// <summary>
    /// Base controller that all controllers inherit from.
    /// </summary>
    public abstract class BaseController : Controller
    {
 
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseController" /> class.
        /// </summary>
        protected BaseController()
        {
            MyData = "I have set this in the BaseController";
        }
 
        public string MyData { get; set; }
 
        /// <summary>
        /// Method called after the action method is invoked.
        /// </summary>
        /// <param name="filterContext" />Contains information about the current request and action.
        protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            // check there is data in the Model
            //
            if (filterContext.Controller.ViewData.Model != null)
            {
                // bit of reflection magic and get the types
                //
                Type _baseFormViewModelType = typeof(BaseFormViewModel);
                Type _modelType = filterContext.Controller.ViewData.Model.GetType();
 
                // if the model type is derived from the base type then
                // we can set some properties.
                //
 
                if (_baseFormViewModelType.IsAssignableFrom(_modelType))
                {
                    // inject the value to the ViewData.Model property
                    //
                    _modelType.GetProperty("MyData").SetValue(filterContext.Controller.ViewData.Model, MyData, null);
                }
            }
 
            base.OnActionExecuted(filterContext);
 
        }       
    }
}

The Home Controller Class

This inherits from the BaseController and also has a Data Class called HomeFormViewModel which inherits from BaseFormViewModel.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace GlobalViewData.Controllers
{
 
    public class HomeFormViewModel : BaseFormViewModel
    {
        public string LocalData { get; set; }
    }
 
    [HandleError]
    public class HomeController : BaseController
    {
        public ActionResult Index()
        {
            ViewData[&quot;Message&quot;] = "Welcome to ASP.NET MVC!";
 
            return View();
        }
 
        public ActionResult About()
        {
            var _formData = new HomeFormViewModel {LocalData = "I have set this in the Home Controller"};
 
            return View(_formData);
        }
    }
}

 

When the About Action is called the  HomeFormViewModel  is populated and then caught by the BaseController OnActionExecuted method which injects the required data into the HomeFormViewModel which is derived from BaseFormViewModel

In About.aspx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
< %@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<HomeFormViewModel>" %>
 
< %@ Import Namespace="GlobalViewData.Controllers" %>
<asp :Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server">
    About Us
</asp>
<asp :Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2>
        About</h2>
    <p>
        Global - From BaseController
        < %=Html.Encode(Model.MyData) %>
    </p>
    <p>
        Local - From HomeController
        < %=Html.Encode(Model.LocalData) %>
    </p>
</asp>

As you can see from the image below the data is populated.

image

Hope this is useful!