If you're stuck in an environment where you're migrating from ASP.NET MVC to ASP.NET WebForms it's good to know that you can actually render your existing WebForms-Controls in you MVC-views. This might sound like a crazy thing to do (and it is in the long run!) but it might be useful if you're stuck between sprints and have perfectly working WebForms-Controls (.ascx
-files) that you don't have time to migrate right now. All you have to do is use the HtmlHelper
's helper-method .RenderPartial(string partialViewName)
and pass it the path to the WebForms-Control.
// Write the content of a control inside a view:
Html.RenderPartial("~/Controls/ControlVirtualPath.ascx");
// Or to get the content of a control as a MvcHtmlString, for further manipulation:
Html.Partial("~/Controls/CustomControl.ascx")
It's important that your controls inherits from System.Web.Mvc.ViewUserControl
and NOT the old System.Web.UI.UserControl
.
One performance-tip that is often mentioned around ASP.NET MVC is to deactivate the WebForms-View Engine for MVC Razor-views (which actually turns out to maybe not make such a big difference after all). This will not prevent .aspx
, .ascx
and other WebForms-files from working.
But you still want your .ascx
-files to work inline in your MVC Razor-views. This can be achieved by implementing your own class
that inherits RazorViewEngine, which only uses the WebFormViewEngine when actually needed.
Global.asax
(or other config-class
)
// Remove WebFormViewEngine (and RazorViewEngine)
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomRazorViewEngine());
CustomRazorViewEngine : System.Web.Mvc.RazorViewEngine
private static readonly WebFormViewEngine WebFormsEngine = new WebFormViewEngine();
public override ViewEngineResult FindPartialView(
ControllerContext context, string name, bool useCache)
{
if (name.EndsWith(".ascx"))
{
return WebFormsEngine.FindPartialView(context, name, useCache);
}
return base.FindPartialView(context, name, useCache);
}
If you need the actual class
of the control to do some further analysis/manipulation, you can do the following anywhere in your code:
var viewPage = new ViewPage();
var control = viewPage.LoadControl("~/Controls/ControlVirtualPath.ascx") as ControlType;