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
Related
We are hosting huge app for our cutomers. There are diffrent configuration and contents (images, user files). But the core code, directories structure, databse scheme is this same for every client.
I'm looking for a way to create one core code repository, so all clientes will use it. We do updates often, so this will make our live easyer.
The idea is to create the repo and In clients directories create just symbolic links to that repo direcories: bin, App_Resources, Css, SystemImages etc.
Is this a good idea? Will ASP.NET MVC app handle this correctly, or I've to add some code for it handle the 'virtual direcotories'?
I would suggest that you take a look Single-tenant and Multi-tenant applications even if you say that your code base is the same for every one.
Here is a nice Multi-Tenancy ASP.NET example
I would also suggest that you check http://appHarbour.com as you can easily push changes from your master repository to appHarbour using Git or Mercurial.
Regarding your exact question, I also keep static files in a custom scheme under Amazon S3, so each client can upload there own files, plus the ones I have and all is based on a single location that does not put more resources just to delivery static files.
You can see my live web application using this technique checking the View Source.
We have a solution with multiple web projects, and there are some pages that should be present in several of them. So we'd need some sort of a shared project which contains aspx files, and which can be referenced by other web projects.
Now there are a few implementations out there:
One implementation described by ScottGu which involves building the shared project, and than copying the output aspx into the host project, and referencing the dll of the aspx. This method has the disadvantage that if the apsx gets modified it must been recopied.
Another option, based on David Ebbo's post would be to convert the aspx into ascx-es which can be referenced as custom controls, and than include those custom-control-aspx-es into the host project inside of some placeholder pages. But my concerns are: can all apsx pages transformed into an ascx? I mean there's no Page.LoadComplete event in user controls for example.
And yet another option is to use virtual directories that map into the shared webproject, as described in a Microsoft KB article. The problem again with this method is that the shared aspx-es must be in predefined directories(that is the virtual directory).
If the name of virtual directory overlaps a physical directory, the virtual overrides it and no pages from the latter can be used.
Is it perhaps possible to merge these two together?
Any thoughts? Thanks in advance
P.S. How about debugging the shared pages?
I solved this problem by making shared Class Library that contains .ascx controls. Have not found real difficulties when converting from .aspx pages to .ascx controls. Found this sample by ScottGu really simple and good place to start. http://webproject.scottgu.com/CSharp/usercontrols/usercontrols.aspx.
The solution which we are using is ScottGu's method, which involves copying the aspx files from the shared project to the host projects.
A post build event in the shared project copies the files to their place, like this
xcopy "$(ProjectDir)Forms\Techs\AddEditTech.aspx" "$(SolutionDir)..\TTAdmin\Forms\Companies" /i /d /y
if errorlevel 1 goto BuildEventFailed
xcopy ....
goto BuildEventOK
:BuildEventFailed
echo POSTBUILDSTEP for $(ProjectName) FAILED
exit 1
:BuildEventOK
echo POSTBUILDSTEP for $(ProjectName) COMPLETED OK
Have you thought about baseclassing the functionality into classes that inherit from Page and place those classes in the shared DLL. All implementing applications could then implement that page by inheriting from it and still be able to change functionality assuming the base classes provide overridable methods. I've had pretty good success with this when I had a lot of pages that were used in many applications and all had the same code. Just a possibility.
Have you considered service oriented development? Build the functionality into services you can share. Build your functionality like widgets. This way you only have one codebase but you can use it in multiple sites.
Think outside the (.Net box)
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.
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.
I'm trying to find a way to generate an enums class dynamically from lookup tables in a database and still have the convenience of a normal class (i.e. intellisense).
I've spent the past few hours trying to figure out how to get a custom BuildProvider to work inside an ASP.NET Web Application. The code works perfectly in a Web Site. I then found an article on MSDN that says
Adding a customized BuildProvider class to the Web.config file works in an ASP.NET Web site but does not work in an ASP.NET Web application project. In a Web application project, the code that is generated by the BuildProvider class cannot be included in the application. For more information, see Compiling Web Application Projects.
Does anyone know if it is possible to generate code dynamically and still be able to 'use' it at design time? Using a web site is not an option. I need to use a web project.
Thanks!!
what is the point of an enum class for a dynamic lookup table? your code references will always be static anyway...
if the initial population of the lookup table is static, make an enum for that and don't reference any other values in the code
If MSDN is saying you can't do it, I'd take another approach. Maybe write a small Console application that writes your Enums.cs file and run it through the "Pre-build event command line". Then, every time you build the web application, the Enums class gets recreated and should be accessible through Intellisense.
Haven't done this myself. Hope it helps.