tags:

views:

66

answers:

2

I created my own CustomController base class that inherits from Controller. Likewise I created my own CustomViewData that inherits from ViewDataDictionary. The CustomController class has a ctor that accepts a CustomViewData as parameter.

All my controllers inherit from CustomController and pass in their inherited CustomViewData. Now I want to be able to call this.ViewData from within my controller and get back the view data I passed in at the controller. Currently I get back a ViewDataDictionary (from the Controller class). So I lost my type information.

How can I retain my type information on my ViewData property in my CustomController derived class without wrapping it in a get/set that does the boxing for me?

+1  A: 

ViewData property is defined in ControllerBase class and you can't override it, but you can do this:

public class CustomController : Controller {

    public new CustomViewData ViewData { get; set; }

}

But be warned, if you access a CustomController instance like this

Controller c = myCustomControllerInstance;
CustomViewData cvd = c.ViewData;

your code won't compile since you'll be using the default implementation of ViewData property and it will return a ViewDataDictionary instance.

Gerardo Contijoch
I fear I can't use the new keyword since it seems to make a parallel instance of the ViewData variable. What I’m trying to accomplish is that before on action executed, some of my fields are filled by the CustomController class.
borisCallens
sort of what i was gonna suggest: but without the 'new' keyword. why can you have a field value for your CustomViewData type and lazy-init it?
cottsak
A: 

I tried several ways to accomplish my goal, but none seem to work save for this ugly solution I knew existed but is .. well, ugly.
I basically wrap the boxing/unboxing in a get/set. I have to do this throughout the entire class chain. So my CommonController does this with a CommonViewData instance, my AbcController:CommonController does this from AbcViewData:CommonViewData to CommonViewData etc. Untill I find a better solution, I'll have to go with this.

public new AbcViewData ViewData { 
    get { return base.ViewData as [bcViewData; }
    set { base.ViewData = value; }
}
borisCallens
is think something along the lines of Gerardo's suggestion is the way to go. you really want to avoid the casting hey
cottsak
Yes, if I could, I would not do so. But when I create an instance in the inheritted controller with the new keyword and then alter the state of the ViewData in the customController, the state isn't represented in the inheritted controller. The new keyword basically hides the previous one (makes it inaccessible, but still existant) so there will now be two instances of viewdata. ContengController.ViewData (is CotengViewData) and one in InheritedController.ViewData (is InheritedViewData).
borisCallens
Call your custom one something else then? as in: property CustomViewData of type CustomViewData.
cottsak
That would still have a duplicate field then, right? I want it basically to be ONE instance of the variable. A the deepest level it will be handled as the most complex type, at a level up it will be handled as a CustomViewData and then one level up it would be handled as a ViewDataDictionary. All the same instance.
borisCallens
Unfortunately there's nothing to do about the duplicate ViewData instance. As I mentioned in a previous answer, that property is not overridable so you'll have to create a new property (with a new internal field) or 'new' the old property and use a new field to store its value. You could also create a whole new controller implementing IController directly but that means you'll basically have to rewrite ControllerBase.
Gerardo Contijoch
Well, the boxing unboxing doesn't seem to have that much overhead where the duplication of viewdata instances will make things a lot more complicated.
borisCallens