Why are ASP.NET pages (both forms and MVC) dynamically compiled? - asp.net

There is a pattern in ASP.NET - whenever there is a piece of markup that generates code (like the .aspx/.ascx files in WebForms or .cshtml files in MVC3), these files are dynamically compiled at runtime. aspnet_compiler will produce another assembly for them, which references your code-behind assembly.
This approach seems awkward to me and I don't understand why it hasn't been discontinued already. A much better approach (in my opinion) is like in Winforms or resource files - you have your .whatever file, and then there is .whatever.desginer.cs file. This designer file is created at runtime as you type. When you compile, the compiler doesn't care about your .whatever file, it just takes the .whatever.designer.cs file and produces a single solid assembly.
This provides several benefits:
You can inherit your forms from each other, similar to windows forms;
You can always see the code that is being generated, possibly adjusting your markup to generate better code;
You can easily instantiate strongly typed instances of your forms;
The only benefit I can see from dynamic compilation is that
You can change the markup file anytime and don't need to recompile the app.
To be honest, I've often wanted for one of the first three benefits, but never for the last one. Recompiling the app to see your changes isn't that big of a deal. Especially since you have to do it anyway when working with code-behind, where the most of your time will be. And when you deliver your app to the client, you deliver it as a monolithic, precompiled block. When you update, you update everything, not just individual .aspx files - there's no point to.
So... why is it like this? What am I missing?

It sounds like you are referring to an ASP.Net Website. An ASP.Net Web Application is like an ASP.Net Website, but uses .designer.cs files and produces a single assembly.
See ASP.NET Web Site or ASP.NET Web Application?.

One thought that comes to mind is that the primary difference between winforms and webforms has to do with the common development model.
Namely, there is a whole class of developers and designers who work strictly in html/css/javascript. They use a host of tools ranging from notepad on up to competing development products to build these pages.
Further, in the case of WinForms, MS has complete and total control of what can make up a form. Any controls that can be dropped on it have to descend from their specified code.
However, with HTML they don't have this same level of control. Spec changes occur out of sync with VS releases, additional features are added that are browser specific, etc. In short, they can't guarantee that a particular element in the HTML file is a valid element at all. All they can hope for is that whatever is sent was done so on purpose and that the browser knows how to deal with it.
Now they have tried to implement a model that provides visual inheritance. It's called "master pages". However, I believe the only tools that properly work with master pages are VS and Expression. Getting the other vendors to go down this path would be nearly impossible. Also, they've added the concept of "nested master pages" such that you can get multiple levels of inheritance out of them.
The code behind model helps to implement non-visual inheritance allowing people to completely revamp page processing (hence how MVCx works).
Which leaves us with the parts that MS does know about. Obviously they do have a .designer file which backs the .aspx pages. This designer file maintains the server control list that is accessible by the code behind. You could add runat="server" to every regular element in an html page (excluding artifacts like css) but this would increase the amount of processing required for the page.
To sum up, I think they've picked the best model they could for web development given the lack of control they have over how the web works. Other vendors have tried similar paths (e.g. Adobe Contribute, previously by Macromedia). I believe some of those even predate MS's model.

Related

Multiple controls in a DLL using Visual Studio

I have a series of custom user controls (ASCX files) which have been tested and are confirmed to be in working order. Using the method provided by Microsoft (https://msdn.microsoft.com/en-us/library/aa479318.aspx) I have successfully managed to create a DLL for each control and reuse them in several different applications.
What I would like to do now is to combine the controls into a single DLL, as importing 5 or so DLL's in each application can be a bit of a hassle, but this is where things tend to get interesting. When I combine the controls by using ILMerge I get results included but not limited to the following:
Controls failing to render entirely
Controls corrupting their Javascript so it shows as raw HTML
Therefore my question is whether it is indeed possible to combine several custom controls into a solitary DLL and if so how? All of my controls are in a single solution and contain both Javascript code and server-side code. Moving the Javascript to a separate JS file would not be a problem but then I would like to know whether it is possible to include the Javascript into the JS file as well.
Any advice is appreciated!
One project with N user controls (.ascx), with inline javascript, etc, no worries. And of course, any other C# classes within the project will also be merged into the same dll (that script is almost what you need, it should put the output dll over the default, so you can use "project references"...):
User Controls (asp.net, ascx-files) inside a C# class library, build error (aspnet_compiler.exe)
I'll see if I can dig up an example project, been a while...
PS: no sample project available, although; if you need it, I could quickly create one.

Building Server Controls like ComponentOne or ComponentArt lirbaries

I'm an expert web developer knowing all famous web frameworks.
I want to build a collection of Server Controls like ComponentArt components that you can use in your projects.
In ComponentArt: You can easily register the namespace of componentart in your project and bind data to those controls without any additional code or effort (like copying any additional files to our sample projects) and ofcourse they support ajax.
To accomplish this I came to realize that I have to develop some advanced UserControls that support callbacks for handling ajax and there are not much of a information about sharing UserControls amongst different projects. Actually here is the only useful link: http://www.codeproject.com/KB/user-controls/EmbeddedUserControl.aspx
On the other hand Server Controls don't have ascx template interfaces that I can comfortably design my control layouts.
I need a way to develop some web components that you can:
Share amongst other projects easily (Just add dll to project and start
using it)
Support CallBack For ajax(for example ICallbackEventHandler)
Can have a Template for HTML Design (like UserControl that have ascx template
file) so you don't have to hardcode HTML in your code like:
output.Write("<table>content</table>");
Custom Server Controls have the first two, but they don't have ascx files so you have to write all of your html code inside your cs file
Please advise...
Instead of hard coding your HTML you could have your Server Controls read it from a file, whose name and path you determine based on a configuration setting or the directory path. That would allow your Server Controls to be more dynamic and not have a need for recompiling upon changing the HTML. That would help fulfill condition #3 at a slight cost to #1 (since your Server Control now relies on an outside resource it's not as easily distributable). You could always hard code the default markup and fall back to it if the file is not found as an extra precaution against exceptions.
Requirements 1 and 3 are mutually exclusive. The markup has to come from somewhere--either a compiled resource or an external file. Your external file could be optional, but then you have to have default markup specified in the compiled resource. The compiled resource doesn't necessarily have to be your .cs file. You could put it in a resource file, but I'm not sure that's going to be any easier to work with. You could also build your control as a composite of existing server controls, but that's going to make your templating much more difficult.
You need to start educating yourself with books like:
Using this book, and a lot of time, I created a multi column TreeView. Can be seen HERE.

ASP.NET project organization

This may be a broad question because part of the problem is that I actually don’t know what the question is. What I would like to know is how you commonly organise ASP.NET applications in terms of placement of pages (aspx), user controls (ascx), server controls and other support classes and utility functions etc. First, let’s assume that there is already some data layer somewhere (perhaps in a different project). This is the not issue.
The issue I frequently face is that create several pages and realize that they need to share some common rendering logic or some utility function, class etc. Another typical case is that some pages become too large so that it seems handy to split them (say into some user controls). What is the best place to put these utility classes, share classes, user controls, server control etc.? Here are several possibilities.
Don’t really care about any organisation and place all types of files next to each other. So in one directory, you may have an aspx files, some cs files etc. This is not really an option probably.
Organize files by types. Let’s say you create a directory for user controls and put all user controls there. OK, but what about server controls and other regular classes? Should they be in special directories as well? It does not sound right. What I dislike most on this is that when you work on a feature (logically related piece of code), you must hunt it all over the place. I think that features and logical sections of your applications should be also grouped on the file system level in some way.
What I would like to have is to have the pages (aspx), user controls (ascx) and handlers (ashx) basically as dummy placeholders sitting in the directory structure organized from the logically according to the point of view of the outside visitor while the actual code (page, user controls implementations, serve control and utility classes) should be placed in s different folder structured into logical namespaces (organized by the modules or features of the application). It seems to me that the only way to achieve this is to manipulate the <%# Page ... %> directive manually.
Does it sound crazy? Am I asking too much? Is there a better way? What are your best practices? Do you know some good examples?
Edit: Another idea. This does not mess up with the generated aspx, aspx.cs and aspx.designer.cs files. One on my original requirements was that I wanted to place the code driving aspx pages to my own location and put it to a custom namespace hierarchy. So what if I simply subclass the aspx classes generated by VS? Let’s say I have a project called MyApp and MyPage.aspx page in it. VS then creates MyApp.MyPage inherited from System.Web.UI.Page. I leave this class be (no code will go there), but create a subclass, say in MyApp.SomeNamespace.SomeSubNamespace.MyPage, inherited from MyApp.MyPage. This way MyApp.SomeNamespace.SomeSubNamespace.MyPage will get access to the autogenerated protected fields corresponding to the server controls of MyApp.MyPage and I’ll get an entire "private" namespace for all the support classes which are related to this page. Any major disadvantages? Another related problem which bothers me is where should this new cs file be physically placed? In web projects, there is a standard folder for it called App_Code, but I’m interested in web applications. Creating a directory in the root of the application (such as Code) does not sound right.
Remember that you can create page classes that don't actually correspond to any markup. We often create base pages that our actual UI pages inherit from. This is a simple way of organizing "base" page functionality. Then when you create your .aspx pages, make them inherit from the base page class, rather than System.Web.UI.Page.
We usually place our base page .cs files into the top level directory if it's a small project, or for slightly larger projects we'll create a "Shared" or similar directory where they live.
However, we also have a huge enterprise web project, and we simply build our webcontrols and base pages into a class library called CompanyName.Web.UI, with a couple sub-namespaces to that. All our actual web site projects import that assembly and all the code for the controls, etc. is elsewhere. This sounds like it might be a good option for you.
If you remember that your .aspx codebehinds can inherit from any class file, it should make it easier for you to organize.

Best way to encapsulate component that includes logic and webforms

I have written a data browsing library that is being used in several projects. The library or component includes some classes as well as some ASPX pages.
Until now, we copy all the files into each project to reuse it, with the obvious drawbacks and updating nightmares. I want to encapsulate all the library into a component that the projects can use.
What's the best way to do it? I know I can create a DLL, but I think it's only for the classes, don't know how to go with the ASPXs pages.
We are using Visual Studio 2008 and Framework 2.0
Thanks in advance
This is a perfect case for custom controls.
Change the pages into user controls, and embed the new user controls back into pages that have nothing in them but the reference to the user control.
Once that works, you can change the user controls into server controls, little by little. They will be composite controls, as the user control already is.
There's a trick you can use at this stage: I'm not recalling the details this late at night, but someone else will fill those in: when ASP.NET compiles a page, it first "compiles" the markup into source code, then compiles the source code. You can get ASP.NET to not delete the temporary source files. That allows you to copy into your project code that creates precisely the same HTML as the user control did.
The difference will be - it's now your code and you can refactor it as much as you like, or even include it in a custom control library.

User Controls - In separate DLL - No design time support / Making Read Only

I want to have a common control library with a whole bunch of User Controls for dealing with common UI scenarios (login etc)
My plan was to have a separate dll for these. But this seems to mean that I lose designer support for them in the referencing application.
Is there any alternative apart from just including a separate copy of each control in the application that makes use of them. This article suggests not
And if I have to include a separate copy. I wonder if there's a clever way to make these controls read only so people can't edit them.
First question: are these web controls or server controls? you'll need to create server controls to do what your looking for.
What you seem to be looking at is to separating your controls to a new project (class library or something similar). Then you can compile and reference it independently wherever you need them, either directly to the project or to the compiled DLL.
You can either include the project in your main solutions, but to keep it read only as you said, you'll need to only provide the DLL to the other projects.
Make sure your controls are set to public, else the designed won't see them.

Resources