Web Application Structure and Deployment - asp.net

Our product is an ASP.Net web application. Currently, we use Web Site Projects in Visual Studio, but have been looking into using Web Application Projects for quite some time. I am currently researching them so that we can hopefully improve our deployment process.
We have a base web site that is shared and common between different clients, and then we extend that with client-specific functionality in client Web Site Projects. The client projects extend base, and therefore rely on its contents. To build the full product, we first deploy the base web site, and then overlay it with the content from the client project.
In looking at converting to Web Application Projects in Visual Studio, we were hoping to be able to create the base project, then create client projects and set up references to base. This structure seems to work OK, but when we are attempting to deploy the application from the client project using MSDeploy, only the dll from the base web site is being published. This is fine for some things, referencing the compiled code is useful, but there are other items like images, js pages, htm, etc that is still source that is required for the client application to function. We need more than the compiled code from our base web site.
That all being said, I can think of a few options here:
Continue to deploy in 2 steps. First the base web site, then the client web site to build the full product.
Modify the deployment process to copy the required source files from the base project
Re-architect our model to support this base-client relationship in a different manner. Not quite sure how this would work, and would be the least-viable option.
??
Is there a different option that I am missing? Am I doing something wrong with the way I am setting up my projects? Is there more to making a Web Application reference another Web Application beyond sharing compiled code? If that's the case, why wouldn't you just use a shared class library? Or maybe I am missing something with the MS Deploy process?
I am open to suggestions here as I feel like I am missing something. I don't think our model for our web applications is too unique.
Update: The dual-deploy process does work, but feels a little kludgey. Any other input?

By using assembly WebResource you can Add CSS/JS/Some other File as Reference along with the Code i.e, your Base Project DLL.
If am right you can Add this WebResource in your base project then go through the below link.
http://support.microsoft.com/kb/910442
Like this way, most of the third party tools will access their CSS and JS files.
Try this. Hope it will help.

How is the site "shared" between clients? Does each client ultimately get a different site (ip address, etc) or are they logging into the same site but getting different functionality? You may want to looking into adding ALL the functionality into a single project and then enabling/disabling feature via settings.

If i have correctly understood your question, you'd like to publish also items which aren't compiled (htm, JS, images, etc..).
So, each file in your Solution Explorer tab has its own properties (accessed by F4 key) which let you choose the build action (eg. compile -> will inject the item in the DLL if applicable, content -> will copy the file "as is" to output directory).
I think the build action "content", with the option "copy to output directory" set to "copy if newer", may be the solution you're looking for.

I would carefully analyze what you are sharing between projects and how you share them.
If it is compiled code, the correct way is to extract those classes out into their own namespace and assembly and share the DLL across projects. Ensure you follow OO and SOLID principles while refactoring.
If it is content (js, htm, images, css) that you share, you have a few options here. You can create a separate virtual directory for the content and reference your content with an absolute URL. This helps because later down the line if you ever want to separate out a project into its own website in IIS, you don't have to change the content URLs. You can also have all the content in your so-called base website and then reference the content in the other projects using a relative path relative to the base website.
On the other hand, if it is ASP.NET user controls or ASP.NET MVC views that you would like to share, it is best to create an individual item in each project. This does not necessarily mean there is a separate physical file in that path - you can also add items in a .NET project in Visual Studio that are only reference links.
Regarding the deployment process, I don't think there is anything wrong with the web site projects per se. Web site projects have a purpose that is different than Web application projects, the main being that you do not have to compile your classes every time you deploy code (provided they are in the correct application folders).
I would suggest sticking to the 2 step deployment process with Web site projects.
I would also review the web sites (virtual directories) created in IIS and consider nesting them if it makes sense. And a review of the application pools (whether separate or shared) would not harm either.
Lastly, this is an old question. Please share if you have already implemented a successful strategy.

Related

Deploy project with same code base but different content to multiple sites

I have an ASP.NET MVC project that is deployed via Visual Studio's Web Deployment - all works fine so far.
I now need to deploy another version of the same project (e.g. for a different customer) - with the same code base/functionality, but with a different layout, i.e. other CSS and images (maybe even with different views/Razor code). Ideally, the content from the other configuration would not be published at all.
I know I can use different connection strings for the persistence layer - but is there a way to configure also configure other content elements?
I'd like to avoid having two versions (or later even more) that required branching/merging - but rather like to simply deploy the latest version with the different "themes"...
I have a MVC project with 4 class libraries. And i deployed it into 3 other domains.
I copied only MVC project without controllers or code classes for each client, and added them into my solution. I use them only for visual changes or themes. Not for server side functionality. So the copied projects' assemblies shouldn't be deployed. Only the UI files should be deployed. Assemblies are deployed from the original MVC project's output folder.
I build solution and publish dll's into 3 domain, and publish only each client's UI files into it's server.
This enables me to develop server-side functionality in only one MVC project. Separate UI files from server side functionality.
Hope this helps.
are you using MVC then?
What you can do is to override the default razor engine and create your own. What the razor engine does is mainly to map your requests to views in particular folders, you can tell the razor engine when to map those requests to views in one folder or another.
MVC4 Razor Custom View Locator
A full fledged explaination is here :
http://nickberardi.com/creating-your-first-mvc-viewengine/
That is for views, if you just want the CSS or JS to be different, you just have to map your requests to a razor bundle and then vary what the content of the bundle is depending on a variable, or the pressence of a configuration file, or by filling a variable with a value from the database.
As you can see here bundling is very easy :
http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
Say your html points to : /assets/mycssbundle.css , but what that file would actually contain can be altered by where you tell to the bundling function that the files are located.
This seems like a design question. If you foresee possible changes like this in the future, and you already swap content via DB, then you should consider loading css file from database. There're of course many other ways to do this but simple and efficient is preferable.
This would mean structuring your html properly to ensure all layout is properly handled via CSS and can be achieved via ViewData or ViewBag. See case example.
Edit:
Not css data but the relevant css file.
You have two options:
A) Develop a custom view engine that switches between different page sets depending on the configuration. This will allow you to switch between the page sets just by changing the web.config settings, which fits well with the visual studio's built in deployment model (different web.config transformations kick-in for different deployment environments). One implementation that comes to mind - switch between view engines for different deployment environments (in different web.config transformations).
Unlike the other suggestion to load pages from the DB, I would recommend loading them from folder or physical location (e.g. different view engines targeting different sub-folders of the project). DB approach is not developer friendly when it comes to developing and fixing pages and their markups that are in the DB.
B) Develop all page sets (all variations) under the same project and then write custom deployment scripts which deploy particular page sets depending on the deployment environment. Drawback of this approach is that it's hard to notice issues like page sets intersecting or links crossing the page set boundaries.
While plan B sounds a little bit simpler development-wise, it can become a nightmare maintenance- and deployment-wise.
So, I recommend plan A.
Your Question is too broad.
However we have also a similar use case. We put all the theme related stuff (css, images, etc) as an embedded ressource in a separate assembly. We have Customer1.Theme.dll and Customer2.Theme.dll etc.
The App loads dynamically the Theme.dll and references the ressrouces from there.
Among other solutions,
assuming that you are using asp.net mvc.
and assuming that you have content1 and content2 folder available in the same repository or making available in same repository is not a concern.
and assuming your are bundling your contents.
and assuming your images are referenced only using css.
You can have a app config key which will tell you whether you want content1 or content2.
something like,
<add key="sitecontent" value="content1"/>
Now in your Application start in global asax, read the app config key and depending on the value, call the
BundleConfig.RegisterContent1Bundles(BundleTable.Bundles);
BundleConfig.RegisterContent2Bundles(BundleTable.Bundles);
I think this is a design issue. As you can see below you can organize your .net application in different layers:
Source: Microsoft
There are some key principles (Separation of concerns, DRY, etc) that Microsoft strongly encourages through the .net platform and I believe will find good use in your project.
Based on what you describe a simple approach is to keep in one project -same for all clients- your business layer (including the Services or the Data layer - even with different connection strings for each project) and create separate projects for the Presentation layer.
You may find more information from Scott, CodeProject, or more traditional methods (BTW this is a great book).

Multiple web applications projects within a visual studio solution

I am currently starting the development of a new website using ASP.Net Webforms. To give this project a proper start I am investigating a visual studio solution setup for the application, where I want my application to consist of easily recognizable components that are equal in size (lines of code).
Since the project is hasn’t actually started yet I have structured the solution in a standard three tier setup (data, business logic and presentation). This setup is fine at the start of the project but as the project grows the three tiers will soon start to become big and navigating and finding code will become harder which will hurt maintainability and overall feel of quality.
So during the project I want to convert to a new setup where I form functional components that each has their own three tier setup. For example: the website has a shopping cart and options to create and manage a user account. There should also be component for stull used across multiple components, which I will call common for this example. That would lead to the following setup:
The common files:
Project.Common.Data
Project.Common.Business
Project.Common.Presentations
The shopping cart:
Project.Shoppingcart.Data
Project.Shoppingcart.Business
Project.Shoppingcart.Presentations
The account management:
Project.Account.Data
Project.Account.Business
Project.Account.Presentations
The website:
Project.Website.Data
Project.Website.Business
Project.Website.Presentations
The sample above has three components that each contains three projects. Each component has one web application project that contains web files (pages, controls, front-end code). All my previous .Net project all had a simple web application project, so this setup is a new experience for me.
I still want the solution to feel as one application, being able to debug the website and the components with ease. To achieve this I assume the “Project.Web.Presentation” web application project should be the main web application project. I am currently investigating if it is possible to setup a solution this way, I have tried several approaches but none have worked well so far:
Running all the web application project separately, this worked fine but I have to run all the application separately and I cannot run them under the same port which is terrible when debugging.
Adding files from other presentation projects as links to the “Project.Web.Presentation” project and set that project as startup project. This doesn’t work as the files aren’t present at debug time, seems to work fine when building a deployment package. I do not want to copy the files since I have to somehow prevent those duplicate files from ending up in version control.
So far I haven’t found a good way to work with setup I have in mind. I am open to suggestions, thanks in advance for the tips!
I'm working on something similar and decided to use NuGet to push out all the common parts:
Multi-Project Nuget Issues
Updating Files in Existing Nuget Package
Visual Studio Multi-Project Solution Options
The only other way to do this involves nested master pages and post build scripts - messy.

Suggestions for an ASP.Net webforms application architecture?

I created an empty Visual Studio solution and added two projects: Backend(Class Library type) that will have the.edmx file for accessing information; and Frontend(ASP.Net type) that will have the database in the app_data folder.
Is this a good architectural design or is there a more proven way to organize this type of application?
Splitting the data access code into a library project is a good idea. I'm currently working on an ASP.NET project which is almost the same - I have a library class that I use to access the data, and in the other project I have my aspx pages. The only difference is that my data is in SQL Server (using entity framework to access that data via a .DBML file).
For the type of site you're building (data in the App_Data folder) it sounds like it will be a simple site which does not need to do anything too intense i.e. scaling.
Most often it depends on the size of your project, but generally I tend to separate the front-end stuff from the backend s.t. it gets reusable. So to that direction your organization is already fine.
If you want to go a step further, I'd take a look at layered application architectures. This post here may give you some insight into that and you may find some reusable elements.
Personally I don't really like the DB to reside in the "app_data" folder of the UI project (i.e. the ASP.net Web Application project). But for small apps it's fine :)

Difference between 'Web Site' and 'Project' in Visual Studio [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
ASP.NET: Web Site or Web Application?
I have noticed that there is clearly a difference in what you get when you fire up Visual Studio 2008 and choose 'New Project' -> 'ASP.NET Web Application' instead of 'New Web Site' -> 'ASP.NET Web Site'. For example if you choose 'Project', then you can compile to .dll and each page gets a *.aspx.designer.cs codebehind file.
1) Why do we have these two different project types?
2) Which do you prefer?
3) Why would I choose one over the other?
4) What's the deal with the *.aspx.designer.cs files?
They have different purposes.
A website is a site with content that is likely to change over time, that is the pages themselves will change. There is no actual project file and the site is deployed simply as a set of files.
An application is a site where the content is just the application, the dynamic part will mainly be in persistant store such as a database. It will have more complex logic since its likely to represent a set of forms for data entry as much as a means to examine content. It has a project file to more strictly control its configuration and its code deployed as a compiled dll.
1) The 'web site' model was introduced with ASP.NET 2.0, the 'web application' model was the project type of the original .net framework. They both have different uses (see below).
2) It depends on the context. A good example is if you are selling a software product, you may wish to use a 'web application' project because it naturally lends itself to cleanly compiled code.
3) See above, personal preference, maintenance characteristics. An interesting thing that a 'web site' allows you to do that can get you in a lot of trouble is making arbitrary changes to code-behind (typically a *.cs or *.vb) file in notepad while the website is running.
4) The designer.cs file is used to store the auto-generated code. "This code was generated by a tool."
MSDN Article describing the differences
Similar stackoverflow question
I won't duplicate the definition of the 2, since that just got answered.
So why use one over the other?
Web Site lets you treat it like a PHP or classic ASP site, where you can make inline changes that take effect immediately.
Pros
You can make tweaks to the site right on the web server
Deploying is as simple as copying the folder
Cons
If you are not making the changes right on the live site, you can get into change management problems, where you forget to keep all your files in sync
You can get runtime syntax errors displayed to your end users, since the only way to check is to manually run every page
Web Application lets you treat it more like how you would a desktop application - there is one deployable that is compiled on your machine.
Pros
Clear, structured change management. You cannot accidently mix code from two different versions. This can be important when there are 2 people involved - one writing the code, and one responsible for putting files on the server.
Because you compile it on your machine, everything gets syntax checked at that point*
Cons
Deployment is a little more involved then just copying the folder from your development machine. However the usage of the "Publish" command greatly simplifies the process of compiling and putting together what files should be copied to the web server.
Any changes need to be done on your machine, compiled, and a whole new version sent to the web server*
*The aspx/html files are only syntax checked if you turn this on in your build options though. It is also possible to edit these files on the server unless they are compiled into your project.
The simple answers are as follows:
New Web Site - creates code behind pages that are compiled at the server when page is requested.
New Web Project - creates pre-compiled pages into one or more assemblies (entire site even), and deployed on server.
Scenario #1 - If a hacker obtains your code-behind files, any database passwords are exposed. These pages are compiled at the time they are requested. You can choose to pre-compile everything into a large assembly. If not, there is more load on the server.
Scenario #2 - if a hacker obtains your assemblies, they will be obfuscated. Obfuscated assemblies are harder to crack. These assemblies are pre-compiled, thus reducing load on the server.
For more information:
Introduction to Web Application Projects
3) WebApplication projects are buildable by MSBuild. WebSites are not (without a lot of tweaking). If you use TeamSystem with automated builds then this is the way to go.
THe biggest difference that no one has really mentioned (except touched on by Annakata) is that with the model where everything is compiled into a single DLL, your have complete control over the classes that your application generates. You know where they are and can always reference them from anywhere else in the application.
With the single page model, you can't do this. You have to get around it by creating "stub" classes in the AppCode directory, and inheriting those in your pages, but even that isn't ideal, and add complexity.
You'll only really come up agaist this stuff if you're trying to develop an intricate dynamic site, where you dynamically load lots of user-controls at run-time based on content. Then, the differences are painfully clear - hence much of our development stalled on ASP 1.1 until we could go back to the same model later.
Nich
Speaking from experience with both: "Web Sites" are used where there is no testing methodology in place, no CI server, and a culture that encourages and promotes "hotfixes" to specific pages regularly. "Web Applications" are the de facto standard where proper software methodologies are followed and there is unit testing (if not full TDD) and a CI server with a focus on writing clean code and finding bugs before the need for a "hotfix" arises.
Sites are the 2003 original .NET way of doing web dev. In my experience they are extremely problematic since lacking a project definition they can't be reused and have issues with modular coding, have issues with TeamSystem integration and namespacing. The one-to-one bind with a domain and lack of real publishing abstraction creates maintenance problems down the line.
The ancient "classic" ASP way of !codebehind is a serious problem because it again impairs code reuse and testing, and the often cited benefits of allowing hot fixes - if ever called upon - is actually a massive signal that you have a failing development process. The ability to hot fix is of course better than not being able to, but it's something you never want to invoke.
You might say that the problems with the web site model were great enough that MS gave us web apps instead. Personally I would never use them for anything beyond demo code... no actually I wouldn't even do that.
At first there was a Web application project (it behaved similarly to the current Web site project). They changed it to reflect what some users requested. However people wanted the old functionality back so they re-introduced the Web site project which behaves like the original Web application project.
I -- and my workplace -- prefer the Web site project
We like that the files of the website are the files in the file system (no need to add them manually)
No idea
Here's two articles I found about both:
http://damieng.com/blog/2008/02/07/web-site-vs-web-application
http://www.dotnetspider.com/resources/1520-Difference-between-web-site-web-application.aspx
Note: A lot of the issues with Web sites have been resolved with the Web deployment project
Update: Fixed the point 1, Web application was there first
If your work needs to leverage oo language features (class hierarchies, namespaces) or if you need to reuse common code among projects (data access, class libs etc.) then the web application project is the only way to go.
The website project (the clue is in the name) is only really good for non-complex 'brochureware' sites (where the pages consist of static content) as opposed to web applications.
There is very little difference, and I would highly recommend using the Web Site model.
The main difference is for a website, some files need to be placed in certain directories (code files need to be placed in the 'App_Code' directory), besides that, it's pretty straight forward.
If having compiled code for deployment is important to you, and you want a single DLL (opposed to the several that are created when you do a normal publish for a web site), then you'll want to get this add-on: http://msdn.microsoft.com/en-us/asp.net/aa336619.aspx

Common code used by multiple ASP.Net Applications

Scenario:
Let's say I have four very similar applications (i.e. most of the functionality is the same, but they are different enough to justify each being seperate applications).
What is the best way to re-use the common functionality code between them? COM+? Web services?
In general I'd typically just have the code in a seperate project (dll), but anytime that's updated, the file has to be updated for each ASP.Net application, and wasn't sure if there was a better way of going about it.
Thanks!
If possible, you can create a Visual Studio solution with a DLL Project and a number of Web Application or Website projects. The web projects would have a "project" type reference to the DLL project, and everything would build at the same time. Then you could use the "Publish" tool for each of your web projects as needed.
If all the apps are on the same virtual server, consider placing the shared assembly in the GAC. This allows you to diverge versions should the need arise, and keeps everything in the same place as a bonus. Downsides: this assembly runs with full trust and you should use policy and CAS to ensure there are no elevation of trust leverage points for external untrusted assemblies. You'll also need to learn about the [AllowPartiallyTrustedCallers] attribute.
As for the other choices, COM+, meh, a bit heavyweight. Good for transactional stuff. Web services, not so good for data heavy services, but if done right, can be fairly maintainable. The more it's shared, the better the pay off.
You can have your project, but instead of adding the common dll to the project reference add the common project to all solutions and then add a reference to the common project.
This way you can have one project on any number of solutions and you have your problem solved ;)

Resources