There's no strongly typed View() method to return an ActionResult. So, suppose I have
class Edit : ViewPage<Frob>
In my FrobController, I will do something like "return View("Edit", someFrob);". There's no checking going on here, so I have to always manually synchronize the view and controller's use of it. This is suboptimal, and I'm not aware of any built-in fixes.
I added this method to my controller base class:
public ActionResult ViewPage<V, M>(V view, M model)
where V : ViewPage<M>
where M : class {
return View(typeof(V).Name, model);
}
Note: The reason I take a view object that's never used is because, AFAIK, there's no way to get C#'s type inference to work otherwise. If I removed the view parameter, I'd need to specify V explicitly, which also means specifying M explicitly too... sigh.
So now, I can do this:
return ViewPage(new Views.Frob.Edit(), myFrob);
I'm specifying the exact view (no problem if it gets renamed), and myFrob is typechecked to be the right model type. The ugly side is that I new up a Edit. Alternatively, I could write:
return ViewPage((Views.Frob.Edit)null, myFrob);
One downside is that the the model must be an exact match. So with a ViewPage>, I cannot pass in a List. I thought this might work:
public ActionResult ViewPage<V, M, T>(V view, T model)
where V : ViewPage<M>
where M : class
where T : M {
return View(typeof(V).Name, model);
}
But C#'s type inference can't figure it out. The other potential problem is that the name of the view type might not be the right name, as I think it can be overridden by attributes. But that's an easy fix if I run into it.
Questions:
- How can I make this syntax cleaner?
- What downsides am I missing here?
Edit: With respect to the Controller knowing about the View, it only slightly does. The only thing it gets from the view is the Type, for which it grabs the name. So that's equivalent to passing in the string name. And the strongly typed model, which must match or it'll fail. So it doesn't really know too much about the View -- its just a trick to get the compiler to catch errors.