tags:

views:

211

answers:

4

Is it possible to take a page object, or maybe just a single ASP.NET control, and render it in a desktop application in some way?

For example, Visual Studio, being a desktop application renders ASP.NET controls in the design surface. I want to do something similar.

Edit: I am brainstorming on how to make a very simple designer for a very simple data entry application. I would have some custom ASP.NET data entry controls, and I want lay users to be able to see what the page might look like as close as possible. So I would want a panel in the application to show the rendered collection of controls, but the panel does not need to be interactive in any way. I.e. no click and drag or resizing of controls, etc. There will be standard windows form controls that the form author interacts with for defining the layout of the page.

I will simply save a list of the controls they added with some other information the "designer"(who are non-technical experts) provides, and I will use that information to later create the actual aspx page, either through a manual or automated process, TBD.

+1  A: 

I don't think that is possible but you can you the WebBroswer control load the asp.net webpage in it.

Shoban
A: 

Yes, it should be possible. To render it mean to get the html of the control, I don't sure how you gonna use that HTML in your application.

Mendy
This does not answer the question.
SLaks
can you explain a bit more?
Shoban
+6  A: 

Yes, it is possible.

You'll need to create a separate AppDomain for ASP.Net, as described here.

EDIT: To render pages, use the following code:

string htmlSource;
var page = (Page)BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page));

page.ProcessRequest(new HttpContext(new SimpleWorkerRequest("", null, null)));
using (var writer = new StringWriter(CultureInfo.InvariantCulture)) {
    using (var htmlWriter = new HtmlTextWriter(writer))
        page.RenderControl(htmlWriter);
    htmlSource = writer.ToString();
}

Note that this code must run in the ASP.Net AppDomain.
To do that, you could put in an a public method of the type you give to CreateApplicationHost.

SLaks
But that creates an ordinary EXE host, not an ASP host. There are different CLR hosts, and they behave differently. While the difference between the EXE and ASP hosts are not as big as between the EXE and SQL hosts (these being the 3 CLR hosts shipped by MS), the differences are exactly in the ASP specifics, like IIS request environemnt and HTTP request. I have never tried to host an ASP.Net compoenent in an EXE host, I'd be courious if it works.
Remus Rusanu
@Remus: I'm doing it in production in my application. It's not CLR host; it's simply a second AppDomain created by ASP.Net.
SLaks
I'll be damn... "Enables hosting of ASP.NET pages outside the Internet Information Services (IIS) application. This class enables the host to create application domains for processing ASP.NET requests." ... Wasn't aware this is possible, but sounds like it does work as advertised. How do you make the fake 'request' to the component hosted in this app domain, and how do you get back the response?
Remus Rusanu
@Remus: See my edit.
SLaks
+1 Thanks, does this require IIS be installed?
AaronLS
@aaronls: No; this has nothing to do with IIS.
SLaks
+1  A: 

I was not able to get the popular answer here to work. This, however, seems to work:

public string AspxToString(string aspx)
{
    StringBuilder sb = new StringBuilder();
    using (StringWriter sw = new StringWriter(sb))
    {
        using (HtmlTextWriter tw = new HtmlTextWriter(sw))
        {
            var workerRequest = new SimpleWorkerRequest(aspx, "", tw);
            HttpContext.Current = new HttpContext(workerRequest);

            object view = BuildManager.CreateInstanceFromVirtualPath(aspx, typeof(object));

            Page viewPage = view as Page;
            if (viewPage == null)
            {
                UserControl viewUserControl = view as UserControl;
                if (viewUserControl != null)
                {
                    viewPage = new Page();
                    viewPage.Controls.Add(viewUserControl);
                }
            }

            if (viewPage != null)
            {
                HttpContext.Current.Server.Execute(viewPage, tw, true);

                return sb.ToString();
            }

            throw new InvalidOperationException();
        }
    }
}

If you're running this from a desktop application, you'll need an AppDomain, see http://stackoverflow.com/questions/3702526/is-there-a-way-to-process-an-mvc-view-aspx-file-from-a-non-web-application

marq