Sunday, September 27, 2015

Asp.Net MVC Intellisense for ViewBag

Introduction/Problem Statement: If you are a typical MVC developer, you might have used ViewBag or ViewData to pass data from Controller to View at times. Also, it is well understood that ViewBag is a dynamic type and hence you will not get intellisense for this. Again, it is a similar case with ViewData which is a dictionary instead and hence no strongly typed support and needs to deal with magic strings.

Workaround: We can easily create our own workaround for this. Here is a sample -
/// 
/// A class to hold the data which can be used to interact between controller and view.
/// 
public class ViewBagHelper
{
    /// 
    /// Gets the current instance of 
    /// 
    public static ViewBagHelper Items
    {
        get
        {
            if(HttpContext.Current.Items["item"] == null)
            {
                HttpContext.Current.Items["item"] = new ViewBagHelper();
            }

            return HttpContext.Current.Items["item"] as ViewBagHelper;
        }
    }

    // TODO: Add your intended ViewBag/ViewData properties here. Ex: To hold an id, do this
    // public int Id { get; set; }
}

Now anywhere you want to use ViewBag just do this - 

ViewBagHelper.Items.MyItem

Where, MyItem is your item name, which is basically a property of ViewBagHelper class. While using this in the View, make sure that you are using fully qualified name or you added the appropriate namesapce in the MVC's Web.Config file. For example, if my helper resides in the following namespace 'ViewBagIntellisense.Helper', then your razor config section of Web.Config should have this - 
  
    
    
      
        
        
      
    
  
The idea is not new, people often do this to avoid magic strings. For instance, 3 years back I myself asked the stackexchange community to review similar pattern. Well, it is still in unresolved state because the answers were not convincing enough. However, I continued to use this pattern in various projects and it worked well for me. Even you can find it in one of my old article

Downsides: The one potential downside which I can think of is, it shares various state representations across the application. However, still the memory footprint will be considerably low, as reference type properties are get initialized only on need basis and value types are inherently lightweight (Off-course, Unless you create one!). 

Recommendation/Best Practice: It is always good to have a Model/ViewModel to exchange data between controller and view. Use this pattern (Or ViewBag in general) only if you have some cross-cutting scenarios where putting the data in Model/ViewModel doesn't make much sense or you have only one piece of data to transfer.

2 comments:

  1. I have read your blog its very attractive and impressive. I like it your blog.

    ASP.NET MVC Online Training in India



    ASP.NET MVC Training in Chennai

    ReplyDelete
  2. Greetings I am so glad I found your webpage, I really found you by accident, while I was searching on Aol for something else, Nonetheless I am here now and
    would just like to say thanks a lot for a marvelous post and a all round exciting
    blog (I also love the theme/design), I don't have time to look over it all
    at the minute but I have book-marked it and also added your RSS feeds, so when I have time I will be back
    to read a great deal more, Please do keep up the awesome work.

    ReplyDelete