What makes an ASP.NET project an application vs library? - asp.net

I am inheriting some ASP.NET code (I am an OS guy, not a web dev (yet ;-)). The solution has been re-factored and there are multiple projects (libraries and asp.net sites) in it. Aside from the libraries, there are two asp.net projects (called MAINSITE and SUBSITE). Only MAINSITE is being used as the official site (as an asp.net site), and MAINSITE has a depency on the code in the SUBSITE asp.net site, but doesn't use the site itself. I am trying to figure out how to clean this up and convert SUBSITE into a library.
My quick question is, whenever I debug the MAINSITE (set as default), it runs two asp.net processes: MAINSITE and SUBSITE. And so, at the very least, how can I avoid this? Is there a quick/temporary solution to this?
My detailed question is this:
What makes an asp.net site an asp.net site? For instance, in C the difference between an dll and exe could be defined (superficially anyway) as the presence of a main, and potential export information for the library (among other things, of course). If I were to convert an exe to dll I might:
1. remove the main code
2. make sure the public interface was correct (and exported correctly)
3. convert the makefile to build a dll rather than an exe.
Can someone point me to some similar steps for asp.net to .net lib?
Maybe:
1. get rid of index.aspx
2. get rid of web.config
3. any *.cs files to remove?
4. how do I change the properties?
5. any gotchas?
Thanks so much for your help.
Details: Visual Studio 2008/.NET 3.5

There are many, many components to make an application run as an ASP.Net application. However, in terms of your actual Web Application project, there's really not that much difference between it and generic library code except for the fact that much of your code relies on the existence of the HttpApplication runtime.
Any code that utilizes the System.Web (especially System.Web.UI) is going to be suspect in terms of having this dependency. For example, all the code in page or webcontrol event handlers (Init, Load, PreRender, etc.) relies on the fact that there is an HttpHandler (running inside an HttpApplication) raising these events. If you run the same WebControl out of a library that's not in an ASP.Net project, none of this will ever happen and the control will be useless. However, that exact same library would be quite functional if executed in the context of an ASP.Net process.
It really boils down to what process you're running the library in. In most cases, ASP.Net processes are spawned by IIS, although it is possible to host an ASP.Net process in other types of programs as well.
There isn't a simple 5-step process for converting a web project to a library unfortunately. But as a rule of thumb, webcontrols, .aspx and .ascx codebehind aren't going to convert.
For a more detailed look at what makes code into an ASP.Net program, see Rick Strahl's "A Low level look at ASP.Net".

If you go to "File" > "New" > "New Project..." and then click on the (assuming you're using C#) "Visual C#" in the list on the left, you're given the ability to create a "Class Library" project. You can extract all the relevant code to one of these and then reference in in your "MAINSITE".
You will need to reference it in the "References" section of your MAINSITE project and may need to import your library project using the import keyword.

Related

MVC conversion project, fully qualified classes are not available unless 'Global' is added or System... is removed

My question is similar to here: ASP.NET System.Anything is not defined
I am in the process of converting a website project to an MVC 4 project. To do this, I created a new MVC project and imported all of my content from the previous website. Both projects are in VB, and I'm using Visual Studio 2010 SP1, with both the MVC 4 update and TFS 2012 update applied.
I now have errors popping up when I build the MVC project. Things like "Type 'System.Web.UI.Webcontrol' is not defined." When I hover over the error, two of the prompts I get to fix it are
1) Change 'System.Web.UI.WebControl' to 'Global.System.Web.UI.WebControl'
2) Change 'System.Web.UI.WebControl' to 'WebControl'
Both of these seem to fix it, but does anyone know why I can't use "System.Web.UI.WebControl" to refer to this class? I'd rather not change all of my code... there are 100s of thousands lines in there.
Update: Outside of the System and System.Web.UI namespaces, I can also drop the 'System.'. So 'System.Drawing.Color' would become 'Drawing.Color'.
There exists another namespace containing System in your solution somewhere (e.g. Abc.System.def) - probably in a referenced library. After the conversion, the project file probably imported the prefix to System in said namespace (e.g. Abc), so when you type in System, it resolves to Abc.System.
I posted this question before I had whittled down as much of the compile errors as possible.
It appears that after I had removed all the System. references from the previous App_Code classes, the real errors started appearing. There were all sorts of messages about aspx controls not existing.
Ultimately, it seemed that I needed to right-click on the .aspx pages from my website project and choose 'Convert to Web Application.' This generated a .aspx.designer.vb file with the asp.net control declarations in yet another partial class.
After doing that for all pages, I am now able to use System. throughout the app.
To others who've asked, this System. error was only affecting the non-page code. .aspx, .aspx.vb, .ascx, .ascx.vb, .ashx, etc., files were not affected.
This does make some sense, anyhow, as I had previously pulled in all the App_Code libraries prior to pulling in the pages, and the site compiled. After importing the pages and their code behinds, the order of the errors was just odd. But I stuck with it and found the underlying cause.
Thanks for the willingness to help. If you have any other questions, I'd be glad to respond.

Compiling/Embedding ASCX templated UserControls for reuse in multiple web applications

I'm onto a real head scratcher here ... and it appears to be one of the more frustrating topics of ASP.NET.
I've got an assembly that implements a-lot of custom Linq stuff, which at it's core has zero web functionality. I have an additional assembly that extends this assembly with web specific behaviour.
The web specific behaviour comes with a couple of user controls marked up inside ASCX templated UserControls.
I'm having trouble putting a nice finish on this assembly so that it is simple to redeploy for use in other applications. Let me run through what I've tried so far:
Copied the ASCX files to the consuming web application using build events; far from ideal and quite a deployment nightmare.
Implemented a custom VirtualPathProvider and embedded the ASCX templates within the assembly as embedded resources. Unfortunately when using the Register directive in the consuming application it creates the designer declaration as a UserControl, where I would require a declaration of the actual control type; unforeseen (typically) and undesirable.
Created a Web Deployment Project to compile the UserControls, but the compiled user controls then become part of another assembly, and no longer descend from the class definitions in my web assembly--the assembly needs to instantiate them dependent on the request context.
So number 1 is just crap, number 2 doesn't give me the type support I desire and number 3 I think I'm about to produce a reasonable solution with:
Lump all non-control classes into the App_Code folder, prepare a factory class that will construct an object of the desired control type using reflection and the expectation that the type being reflected will be present in the deployment output (hopefully guaranteed by the presence of the ClassName attribute in the Control directive).
Theres also always the other option of rewriting the ASCX controls into custom controls, but just don't have the resources to consider it at the moment, and we've got no expertise in doing that, and they work fine as UserControls.
Am I missing something obvious, something maybe much simpler, or is this just purposefully difficult? I've read stories of the ASP.NET compilation process being very unfortunate in it's design on my travels across this topic.
Well I think I've done it ... by being mindful of a few of a few annoying pitfalls with my last approach, I recommend the following when compiling ASCX user controls in a Web Application Project using a Web Deployment Project:
Avoid putting classes in App_Code unless they're standalone or helper classes, ASP.NET treats this as a speshul folder, the meaning of which is lost on me, mayhem, confusion and chaos follows. Code in this folder does get output in the Web Deployment Project, though.
Pay close attention to your assembly names, their root namespaces and deployment output assembly name- you'll get access is denied errors if you have any naming conflicts during the aspnet_merge process.
Ultimately you'll most likely end up deploying 2 assemblies, I tried to create only one but the deployment output was still pointing to type definitions in the source assembly. This isn't a problem if you don't have any other types in your Web Application Project--I have so it was a problem for me. In my case, my final output was:
<Organisation>.<TechnologyName>.Web.DLL - Compiled Web Application Assembly (containing the ASCX templates)
<Organisation>.<TechnologyName>.Web.UI.DLL - ASP.NET Compiled UserControl assembly, created by Web Deployment Project
Clean often, and check that the Web Application Project's bin and obj paths are cleared of any previous junk built when you perhaps hadn't finalised your namespace or assembly naming scheme--the Web Deployment Project will be quite keen to include these, causing a fine mess.
Check your imported namespaces, the ASP.NET compiler likes to refer to the Import directive in the ASCX template, and it also considers imported namespaces present in web.config's <configuration><system.web><pages><namespaces> element, tweak if you get unknown definitions appearing during the deployment process.
Have some patience spare, it's quite tricky! But you do get some nice re distributable UserControls at the end of it!
Phew!

How do I share user controls between web applications in ASP.NET?

This question is a follow up to my question about sharing resources between web applications, because I have not yet found a good solution.
I have a web application with user controls and resources that are shared by three other web applications.
Solution
|
+-CommonControlsWebApp
| +- resources
| | +- images
| | +- scripts
| | +- stylesheets
| +- UserControls
|
+-WebApp1
|
+-WebApp2
|
+-WebApp3
This is what I know this far:
I can not compile CommonControlsWebApp into a single dll since I am creating user controls. This is only possible with custom server controls, where everything is in the code-behind file. So I need a way to share the ascx files between the four projects.
Copying the files from CommonControlsWebApp into the three other projects does not update their files in the solution explorer. I would have to 'add exting items' all in all three WebApps when a file is added or renamed in CommonControls.
Changing to the Web Site model would remedy this, but I am worried about the compile time for WebApp1-3 if I do this.
'Add as link' does not work for directories.
I could use Subversion to share the files between the projects, but i believe that this would require me to check the files in and out again all the time if I am developing a user control that I have to test through one of the WebApps.
Can it really be true that ASP.NET does not have a good solution for this? How are you guys organizing large web applications?
Edit: Thanks a lot for all the answers. I am going to copy my user controls with a build event for now, and then see if we have time to refactor them into server controls.
The way we do it at my present company is to make sure CommonControlsWebApp
is a WebApplication, not a web site. Then you use names for the folders that would help identify it as the common ones that are distinct from the individual web apps. (CommonUserControls instead of just UserControls)
In your other web apps, you create a virtual directory to the CommonUserControls, etc, and add a file based reference to the CommonControlsWebApp.dll
This requires you to use IIS for development (not casini), and Visual Studio won't believe that the controls really exist, but it will work at runtime, and you can build just fine with only warnings about blahblah.ascx or blahblah.master path invalid.
If you do use common master pages and Visual Studio 2008, you will need SP1 for 2008 and use a __fallback.master in the root of the individual web projects to go in to design mode.
However, I saw this on another thread, and I am going to look into doing more like this:
http://webproject.scottgu.com/CSharp/UserControls/UserControls.aspx
You could compile it into a dll
Turning an .ascx User Control into a Redistributable Custom Control
Brief Outline of the Steps
The basic steps to make this happen
are as follows:
Write your user control as you normally would, typically using the
Visual Studio designer.
Test it using a simple page before trying to deploy it.
Deploy the application to precompile it.
Grab the user control's assembly produced by the deployment step, and
you're essentially done: You have your
custom control.
Finally, use your custom control in other apps
Further info here http://www.nathanblevins.com/Articles/Compile-a-Web-User-Control-into-a-DLL-.Net-c-.aspx
In order to share controls between web apps, the only way I found was to either rewrite them into server controls or to use virtual directory to make the user controls actually in folder be in each project.
Unfortunately, asp.net doesn't really have a good solution for this. The same is true for sharing master pages.
You might consider using source control and sharing your controls at that level. We do this for a sizable user control library and it works quite well.
Using SourceGear Vault but you should be able to do this with any source control product.
Check this post for how to solve this issue.
The basic idea is to change your project to have a prebuild step to copy over the .ascx files to a subdirectory of the web application. Then just refer to those copies when using them. Of course you also need to reference the UserControls assembly as well.
One option is to try "Add existing" and in the dialog that appears, the OK button has a drop arrow next to it, change it to Add with a link.
If that doesn't work, rewrite your controls as Custom Controls.
It will take a little while, but will make it much more maintainable in the future.
hey this is not the best way to do things but i used to do this in my asp.net 1.1 days - you can try this - shift your user controls into a seperate project, and publish this project as a virtual directory under iis
as long as you are not using codebehind - your updates would be cool (only update shared user control folder)
if you do use codebehinds - redeploy the user control dlls into different projects
once you are done with this - map these user controls into all projects using their virtual paths
check these links - http://aspadvice.com/blogs/ssmith/archive/2006/10/05/Tip_3A00_-Share-User-Controls-Between-Applications-in-ASP.NET.aspx
AND
http://www.123aspx.com/redir.aspx?res=30887

How to convert ASP.NET website to ASP.NET web application

I have an ASP.NET 3.5 Website (visual studio lingo), but the site continues to grow and is looking rather cowboyish among other things. I'd like to see this get converted into a Web Application (namespaces and all).
Is this something that can be easily done in Visual Studio? If not, are there any other tools out there that could create all of the namespaces, etc. automagically?
Well, it turns out that the option "Convert to web application" does NOT exist for "websites". The option "Convert to web application" does exist only for "web applications" !!!!
[emphasis mine]
So, here's the deal, to do the
conversion, you need to:
Add a new "Web Application" to your VS 2008 solution (File->Add->New
Project->C#->Web->ASP.NET Web
Application).
Afterwards, you copy all the files in the old "website" to your newly
created "web application", and
override any files created in it by
default
The next step is the most ugly, you need to "manually" add the references
in your "website" to the new "web
application". I thought the VS 2008
PowerCommands toy would do this for me
as it does copy references from other
project types, but it didn't. You have
to do it by yourself, manually, and
you have to be cautious in this step
if you have multiple versions of the
same assembly (like AJAXToolkit in my
case) or assemblies that have both GAC
and local versions or so.
Keep repeating the last step and trying to build the "web application".
You'll keep getting errors like "
'....' is unknown namespace. Are you
missing an assembly reference? ". Make
sure you have none of those except the
ones where '....' is replaced by the
IDs of the server controls you use. In
other words, keep adding references
and building the project until only
the errors that exist because of
missing .DESIGNER.CS or .DESIGNER.VB
files.
Afterwards, go to the "web application" root project node in VS
2008 solution explorer, and right
click it, then you WILL find the
option "Convert to web application".
What this option does is actually
making small changes to the "#Page"
and "#Control" directives of pages and
controls, and creating the required
.DESIGNER.CS or .DESIGNER.VB files.
Try building the "web application" again. If you get errors, see what
references may be missing and/or go
click the "Convert to web application"
again. Sometimes, if there's any error
other than those caused of missing
DESIGNER files, not all the
pages/controls will have those
DESIGNER files created for them.
Fixing the non DESIGNER problem and
clicking "Convert to web application"
again should do the job for this.
Once you are done successful VS build, you should be ready to go.
Start testing your web application.
Optionally, you can right click the
"web application" root project node in
VS 2008 Solution Explorer and click
"Properties" then go to the tab "Web"
to set the "web application" to a
virtual folder in IIS (you can create
new virtual directory from there in
VS). If you want to use the IIS
virtual directory that the old
"website" used, you need to remove
that from IIS first.
Update: When testing your pages, pay MOST ATTENTION to classes in
"App_Code" folder, especially those
with NO NAMESPACE. Those can be a big
trap. We had a problem with two
extension method overloads in the same
static class that had no namespace,one
extends DateTime? (Nullable)
and calls another overload that
extends DateTime itself. Calling the
other overload as extension method
passed VS 2008 compilation and gave us
a compilation error ONLY IN RUNTIME
(With IIS). Changing the call to the
other overload from calling it as
extension method to calling it as
normal static method (only changing
the call in the same class, calls from
other classes remained extension
method calls) did solve this one, but
clearly, it's not as safe as it used
to be in VS 2005. Especially with
classes with no namespaces.
Update2: During the conversion, VS 2008 renames your "App_Code" to
"Old_App_Code". This new name sounds
ugly, but DO NOT RENAME IT BACK. In
the "web application" model, all code
will be in one assembly. In runtime,
the web server does not know what web
project type you are using. It does
take all code in "App_Code" folder and
create a new assembly for it. This
way, if you have code in folder named
"App_Code", you'll end up with RUNTIME
compilation errors that the same types
exist in two assemblies, the one
created by VS, and the one created by
IIS / ASP.NET Development Server. To
avoid that. leave the "Old_App_Code"
with the same name, or rename it to
ANYTHING EXCEPT: "App_Code". Do not
place any code in such "App_Code"
folder and prefereably do NOT have a
folder with such name in your "web
application" at all.
I know this since before but forgot it
now as I have not used "website" model
for long :(.
Walkthrough: Converting a Web Site Project to a Web Application Project in Visual Studio at MSDN
If your website application grows.. it's better to split it into several projects. Conversion from Web Site project to Web Application project won't help much.
If you're having problems getting your new Web Application Project to build check the File Properties in Visual Studio of all 'helper' classes. For a project I was converting the Build Action was set to Content whereas it should have been Compile.
I've now successfully migrated one Website project to a web application and there is quiet a few gotchas to look out for.
Having ReSharper at your disposal helps a lot in refactoring the aspx files.
Set up your solution and create an empty WebApplication
Copy all file over
aspx files in website projects don't have a namspace. Wrap your classes in the appropriate namespaces
During copying, all my pages in subfolders got renamed to my project name and the foldername, so I got 40ish public partial class FolderName_Projectname : Page If neccessary rename all files using Resharper or manually.
If you encounter multiple errors like "There is already a member Page_Load() defined", this is most likely due to incorrect class names und duplication
After adding a namespace
Replace CodeFile in all aspx pages with Codebehind and especially pay attention to files i your subfolder. Make sure Inhertis="" doesn't contain the relative path. Your namespaces take care of everything. So the correct format is Inherits="Namespace.classname".
If your class has a namespace NaSpa and a filename foo.cs it would be Inherits="NaSpa.foo"
After you have prepared all your files (don't forget your master pages), run "Convert to web application". If you encounter errors afterwards, rinse and repeat.
If you encounter errors of the sort "TextBoxName can't be found are you missing a reference", make sure you did not forget to sanitize your aspx pages. A good indicator is to check the automatically generated designer files. If TextBoxName does not appear in there, the conversion did not succeed completely.
Resolve any missing dependencies.
Build
Create a New Web Application in VS 2010.
1. Using Windows Explorer copy all your files into you project folder.
2. In VS 2010 solution explorer show all files.
3. Select the files and folders - right click include in project.
4. Right click the project solution explorer and select Convert to Web Application.
There are quite a few small differences, such as the App_Code folder will get renamed to old_app_code - that surprisingly doesn't cause any errors. The TypeName on your object data sources and the inherits on the #Page tag might need the [ProjectName]. prefix appended globally. For example if your type name was "BusinessLogic.OrderManager" and your project name is InventorySystem you would need to change it to InventorySystem.BusinessLogic.OrderManager. Also a few display changes, such as required field validators don't default to red font anymore, they default to black.
I was facing the same problems initially. After following the Wrox Professional ASP.NET 4.0 book, I found the following solution for my case.
I first created a new web application. Copied all the website files into the web application folder. Right click on the application, and click conver to web application.
You might ask why you need to convert a web app into a web app. The answer is, that when you create a website, you simply code the .cs file where-ever required.
A web application, however declares .design.cs (or .vb) and a .cs file for the code and design section automatically.
NEXT: Remove all manual references, like 'Inherits' attribute in the PAGE directive, to other files in your website, since name spaces WILL take care of referencing the classes centrally.
I also faced a problem, since I had not included OBJ and BIN folder in my project.
If you think you are missing your BIN and OBJ folders, simply click the 'Show All Files' icon in the Solution Explorer and then right click on the missing folders and add to project. (to make sure they compile with the project.)
UPDATE:
As #deadlychambers points out in the comments: You can search everywhere by doing a "Ctrl + Shift + F" and then search for Inherits="(.*?)". This will find all occurrences and probably save you some time!
the default ASP name space does not seem to work anymore. So I cannot seem to call my User Controls.ascx pages from outside the page. Giving them a namespace and changing the default from ASP to my namespace seemed to work.

ASP.Net resource files

I'm using selenium to run some functional tests on the UI for our current application.
I want to ensure that strings from the resource files in the Web project are being displayed at the correct time and place.
Simple (I thought) all I have to do is reference the assembly of the web application and assert that the text selenium is reading from the UI matches the test in the approriate resource file.
The problem is the ASP.Net does some precomilation processing on the resource files and compiles them into an assembly called App_GlobalResources, which isn't created by the normal build process so the functional tests fail because that can't find the App_GlobalResources assembly to look the string up from.
So, any suggestions? Do I need to abandon the App_GlobalResources approach and do something manual that I have control over?
Do you understand the problem or do I need to provide more info?
My interim solution is to use SVN:Externals to pull a copy of the resx files into the test project.
I can then access them via
ResourceManager resource = new System.Resources.ResourceManager("My.Web.Namespace.resources.ImageUrls", Assembly.GetExecutingAssembly());
Its ugly because I already have a reference to the webproject (which I can probably remove now...) and I don't like mixing source files between projects. It just feels like asking for trouble but until someone suggests something better this will have to do.
Have you considered moving your GlobalResources into a separate assembly and then referencing that from both your web project and your test project? This is quite easy to do in VS 2008, and achievable but a little more difficult in VS 2005.
I was able to solve a similar problem using that approach.

Resources