Search code examples
asp.net-routingasp.net-webpages

How to set the System.Web.WebPages.WebPage.Model property


I am planning on creating a custom route using ASP.NET Web Pages by dynamically creating WebPage instances as follows:

IHttpHandler handler = System.Web.WebPages.WebPageHttpHandler.CreateFromVirtualPath("~/Default.cshtml");

How can I supply an object to the underlying WebPage object so that it can become the web pages's "Model"? In other words I want to be able to write @Model.Firstname in the file Default.cshtml.

Any help will be greatly appreciated.

UPDATE

By modifying the answer by @Pranav, I was able to retrieve the underlying WebPage object using reflection:

    public void ProcessRequest(HttpContext context)
    {
        //var page = (WebPage) System.Web.WebPages.WebPageHttpHandler.CreateFromVirtualPath(this.virtualPath);

        var handler = System.Web.WebPages.WebPageHttpHandler.CreateFromVirtualPath(this.virtualPath);
        var field = handler.GetType().GetField("_webPage", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        var page = field.GetValue(handler) as System.Web.WebPages.WebPage;

        var contextWrapper = new HttpContextWrapper(context);
        var pageContext = new WebPageContext(contextWrapper, page, context.Items[CURRENT_NODE]);

        page.ExecutePageHierarchy(pageContext, contextWrapper.Response.Output);
    }

Unfortunately this is not reliable as it does not work in Medium Trust (BindingFlags.NonPublic is ignored if application is not running in full trust). So while we have made significant progress, the solution is not yet complete.

Any suggestions will be greatly appreciated.


Solution

  • The Model property of a WebPage comes from the WebPageContext. To set a Model, you could create a WebPageContext with the right parameters:-

    var page = (WebPage)WebPageHttpHandler.CreateFromVirtualPath("~/Default.cshtml");
    var httpContext = new HttpContextWrapper(HttContext.Current);
    var model = new { FirstName = "Foo", LastName = "Bar" };
    var pageContext = new WebPageContext(httpContext, page, model);
    
    page.ExecutePageHierarchy(pageContext, httpContext.Response.Output);
    

    The model instance should now be available as a dynamic type to you in your page.