Deploy project with same code base but different content to multiple sites - asp.net

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).

Related

Implement a multiple web project structure in asp.net webforms

I'm working in a web application that has several areas of bussiness work. With time it's size has became a problem to develop on and to maintain.
I would like to break the web project into several sub-projects or libraries depending on a main root web project that has the common files to share (Masterpages, Resources, Css, etc...)
Ideally I would like to have some kind of injection that allows me to optionally publish that "components" or simply publish a customized variation, although it's configuration depended on after deploy DB setup.
I searched all over the web, reading all the pages related to multiple projects, dependency injection and composite apps that I could find, 'till I soften my head, but couldn't find anything really useful.
Major part of the writings where a theoretical approaches or unit testing applications (well, you can't make your desired app, but you still can unit test something else)
Other approaches simply don't work in VS2010 .Net 4.0
Can someone address me on a COMPLETE solution or an example? Or simply lets discuss.
We say that the solution has the following structure, with module contents already separated into directories:
Solution
L_ Datalayer library project
L_ Bussiness logic /common utils library project
L_ Web project
L_ Controls
L_ Images
L_ Css....
L_ Warehouse
L_ Sales
Masterpages
...
Warehouse and Sales contains pages related to the "module"
Thanks,
I post my progress in the subject.
As per suggestion of Steven I experimented further more using MEF. Due to the lack of documentation, specially for webforms, that was a pain in*. So far I managed to implement MEF in my solution and sucessfully inserted a plugin project visible for the main app.
Then loads the available plugins, through an interface that has the plugin name, the default page url and its order, picks all this data and render a menu tab. That part it's easy.
Clicking on a menu element must redirect to the main page of the plugin, which will render several menus for its pages contained (from another export interface)
I finally got an aspx page embedded as a resource in the plugin project. Where I'm currently stuck.
¿Is there any way to render a page embedded as a resorce on a libray using MEF or I'm forced to also use a VirtualPathProvider? ¿Hows specifically the statement to redirect to that page? I've tried several ways but no-one works (MEF and VirtualPathProvider)
I looked at zillion of articles that talk about it but all them end doing control rendering, not page. So frustrating.
Though it is not an answer to your question, I am adding it as answer due to length of my suggestion.
I suggest you look into the approach NopCommerce is following where they have extended over .net with their own framework, which supports Plugins and extensions to existing solutions. Though I definitely know that nopcommerce is an ecommerce solution but if you study it, you can modify it according to your business needs or at least it can give you a heads on for what you should adopt while designing your solution. Hope it helps.

Web Application Structure and Deployment

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.

How can I split a single visual studio project into multiple projects?

Right now I have a single ASP.NET solution with one project in it. The problem I'm facing is that multiple developers are working on different parts of the project that are getting released at different times. Because of this my project manager is thinking we can split the project into multiple dlls instead of just one dll so that we can update just the modules that need to updated.
1. Is splitting the project into multiple projects (multiple dlls) the correct way to solve this problem?
2. If so, how do I do this?
Can I just copy the appropriate aspx/cs files to the new project, remove them from the old one and build? What about Master Pages, CSS, Javascript and User-Controls, will I need to copy those along as well or can they be referenced in the "Core" Project? Would I need to make some adjustments in IIS or can I just copy the aspx from the new "sub-project" to the root of the "Core" Project (essentially where the aspx files are now)?
3. If not, what is the better solution to fix my issue?
Thanks for your help
Edit (to add a bit more clarity):
Right now our structure is something like this (shortened and code-behind implied):
MasterPage.master
styles.css
SplashPage.aspx
Page.aspx
AnotherPage.aspx
a_MasterPage.master
a_Page.aspx
a_AnotherPage.aspx
b_Page.aspx
b_AnotherPage.aspx
b_AlsoAnotherPage.aspx
Can I take all the a_ pages and roll them into one project and all the b_ pages and roll them into another (which would separate the dlls).
If this doesn't make sense please ask and I'll try to explain it better
Yes
How? Don't think in terms of pages, but rather functionality. The best way to handle your issue is to move the business logic out of the ASP.NET experience layer project and put it in class libraries. You can then have different types of developers working on different types of code.
Now, if you truly have different "sites", meaning they serve different purposes, then you may have to move some pages to one and other pages to another. I can't answer whether that is a need or not.
Hopefully, this all makes sense. NOTE: If you code is contained in Page_Load() and event handlers, you are pretty much screwed until you can refactor the code into individual methods.
3.) What about some version control system, wouldn't that serve you better?
Splitting project like this isn't a good idea imo, it would make sense, if you would like to split logical/physical layers of that project (you could have different project for your data access, another for business logic etc.) But splitting to projects, where one contains "welcome.aspx" and second one "contact.aspx".. hmm I would rather use SVN / Git / TFS / Whatever ;)
Normally you split the project according to the function or feature eg. you could split off the data access layer into a different project.
I ussually try to keep my view together and separate the core features, so it would be easy to use the same dll's over different websites.
eg: I have a project with all the methods and a db for user management.
I could deploy this project on a server and reference it in all my websites.
This way users can use the same login over all my websites.
So once you have a core system, everyone can make his own project and just reference the projects needed.
Yes you just move your aspx/c# files to a different project and reference the new project in your existing project.
I do think that every project needs his own masterpage though (last time I checked that is).
I hope this answers you question.

How do most people organize code within an application (sub folders)?

In a website, I see some developers put code into app_code, and sometimes appcode (due to some bug), other files into DataModel, and other files into miscellaneous folders.
Is there a standard approach to organizing code within an application?
How is it different between an ASP.NET, MVC, Silverlight, Console, Database, and WCF application? The reason I mention WCF is because many people seem to have a shared types library that is linked between the server and client code.
Where can I learn these common practices without having to try, fail, and try again. I'd rather just learn it once from the experts.
the most standard well organized is MVC framework. For anything else, mostly i organize folders as namespace.
eg companyName.projectName.folderName
myCompany.StackOverFlow.Extension
myCompany.StackOverFlow.OpenID
There is no set in stone 'best practice' standard for organizing namespaces. My personal approach to keeping projects organized is to limit the content of any directory/namespace to about 20 items. This means I can fit the full contents of a folder into my screen, and also see every other item surrounding it (assuming other folders are collapsed).
On the other hand, lots of folders without much content can make navigation difficult as well.
Another thing you should do is to separate your solution into projects based on dependencies. For example if you are using m-v-vm, you should have a project for each of Model, View, and ViewModel.
Files placed in AppCode should only be files directly relevant to the presentation modules. Other files (ie ViewModel, Model, Controller etc depending on the framework you're using) would be preferably placed in separate projects.
Take a look at the "WCF the Manual Way…the Right Way" http://www.code-magazine.com/Article.aspx?quickid=0809101

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 :)

Resources