What are some ways to support multiple websites with a single code base? - asp.net

I'm writing a pretty straight forward ASP.NET MVC web app: only a couple of CRUD pages, some folders where clients can browse documents and just 3 or 4 roles. The website will be used in a B2B scenario, where every client will have their "own" website.
At this point, the only thing that will change in the website, from client to client is the content (ie. the documents, and the rows of data they'll see). If this is the case, what's the best way to manage roles across all of my clients? I'm looking for the simplest possible solution because this is a proof of concept and I don't want to invest a lot of time right now.
What if it's not just the content that changes? Maybe some clients will want a few custom static pages. At this point, is my only option replicating the entire website? I'm leery of this because it'll become hard to maintain if I get a lot of clients.
I'd appreciate any help... I just don't want to shoot myself in the foot; I'm sure someone has done this before.

I create Virtual Directories in IIS for each client, all pointed back to the same folder where my ASP.NET code resides.
This allows me to support several dozen nearly-identical "web sites," each with their own database that is basically identical in form, only differs in data.
So, my site URLs look like:
http://mysite.com/clientacme/
http://mysite.com/clientbill/
http://mysite.com/clientcharlie/
There are two key implementation details I worked out for this:
I use the Virtual Directory folder name to determine which DSN my code reads from. This is accomplished by creating a simple static method that injects the folder name into a DSN string template. If you want to use the same database to store everyone's data, you can use the folder name as a default filter in your queries.
I store the settings for each web site (headers and footers, options, links to custom reports, etc.) in a simple "settings" table in each database (key, value) rather than in the web.config (which is shared). This allows me to extend the code base over time to customize the experience for each client without forking the code.
For user authentication, I use Basic authentication, and I keep usernames, passwords, and roles in a table in each database.
The important thing is that if you use different SQL Server databases for each client's content, you need to script any changes to your database tables, indexes, etc. and apply them across all databases at the same time (after testing of course). One simple way to do this is to maintain an Excel sheet with a table of database names and a big "SQL" cell at the top. Beside each database name, create a formula to "USE databasename;" and then concat the SQL code at the top.

I'm not sure if this answers your question completely, but as far as maintaining custom "static" pages I found myself implementing a system on a client's MVC website where the client can create "Pages" from their admin control panel and each Page has a collection of "PageContent" entities which consist of a Title and and HTML content field (populated using a WYISWYG editor). Upon creating a page the MVC application maps http://yoursite.com/Page/Page-Url-Specified-By-The-User to that page and renders its content there. Obviously, the pages are dynamic, but as far as the client can tell they have created a brand new custom page with little or no effort.

Related

Multiple ASP.NET MVC code-first sites using the same DB/Auth/Model/backend - how?

So I may have a bit of a strange situation here, and I need some guidance.
The company I work for has a number of small sites, with each site selling a different custom program. The sites are badly in need of an entire rewrite from top to bottom, and my boss has agreed that a login and online purchase/registration is required. This means user accounts, the ability to download a trial from within the user account, the ability to register that trial also from within the user account and the ability to view a list of previous purchases/registrations and product keys.
The thing is, I want a sign-on from one site to be usable on another. Plus, all of this will need to be administered (on our end) from one admin interface. So my thought is that this will all have to be driven by a single database.
Just to be clear: the front-end for each site needs to be different - sometimes only subtly, but in some cases by quite a bit (marketing differences). The backend (both Admin as well as for the Client interface), is identical in structure regardless of the site URL, but the Client interface needs to show different content (programs to download, lists of computers where the program has been registered on, etc.) depending on what URL is being used.
My problem is that I am not entirely sure how to do this from a code-first perspective. The sites are small, quite easy to build on their own, but I want them all within the same Solution so that a change to the model will be reflected across all of them (I will be able to see where things go sideways if the model gets altered - Intellisense is my friend!).
I have looked into Areas, but Areas seem to be a way of partitioning off gross differences within a site (things like resource files - JavaScript, CSS, etc. - remain in the root, whereas in my case each site will need different resource files). I need each section to be its own unique site, with its own unique URL. When this gets pushed to the server, I need each site to be “independent” in that they can sit in entirely different accounts on the same Windows Plesk server (Plesk was not my choice, but the company has clients that need a control panel interface to their own accounts). The only strong commonality between any of them is the database that they will make use of -- in fact, all of them will be making use of the same tables, with very few differences between the sites.
My other problem is that I do not know how to properly implement having multiple projects within a single solution, and all projects making use of the same model that is implemented/constructed only once. I have not yet made the jump to Repository Patterns, so I am completely in the dark with respect to that functionality.
If anyone has a suggestion, I would love to hear about it.
Essentially, you just need to create a class library where you will put your entities and context. If you're using Identity, you'll also put all the Identity-related entity classes here. You'll enable migrations on this class library. The other projects in your solution, then, will have a reference to this class library. You'll need to add the connection string to the individual projects' Web.config files, but other than that, everything will just work.
This is enough to ensure that all the projects are working from a common database and user store. However, in order to actually share authentication, such that signing into one, signs you into all them, you'll have to take one of two paths, depending on how they will be deployed.
If all of the sites will be on the same domain (different subdomains are fine). Then all you need to do is generate a machine key and ensure that each site uses the same machine key in its Web.config. The auth cookie will be added on the wildcard domain, and any subdomain of that domain will be able to see it. Sharing the machine key is to ensure that they can each decrypt it what any one them sets as the auth cookie.
If not all the sites will be on the same domain, then you're in for some pain. You'll have to set up a SSO system, which is non-trivial and far beyond the scope of Stack Overflow to help you with. There's entire companies devoted just to building SSO systems for organizations.

Sitecore auxiliary content database

Not sure if this is stackoverflow typically question (I'll remove it if suggested), still may help me understand the possible options here.
I would like to know if it's somehow possible beside core, master and web instances to append new content database (let say for some form's filled with data by web users with CRUD repository using existing sitecore api). Editable/readonly from CMS, visible for exports, reports or charts via CMS using custom modules.
Somehow this DB should be located on the same level with Web Database, it's important to follow templates and functionality from sitecore legacy functionality.
This entire shebang will be used in as Sitecore Custom Module (installation, integration customization, management, blah, blah blah). Important: Items stored in this database are pure data items.
I found vague information on John west Sitecore blog, so what I asking more then the direct solution in front of my eyes references or examples how to, or signals if it's against the policy.
Best reference until now: http://intothecore.cassidy.dk/2009/05/working-with-multiple-content-databases.html article written by Mark Cassidy.
The reason you don't find much information on this is because its very uncommon to add another database which is accessible to Sitecore as per the john west blog. Note the data of that post also. I'm not aware of your requirements but I have never seen it done or found a need for it.
With user input data such as forms, comments etc. You have three data considerations storage, access and reporting. In a scenario where you would like to store this data and access it in Sitecore. I would approach it as follows:
Storage of that data should be in the master database inside a bucket. From version 7.0+ buckets were introduced so you can add virtually unlimited data to a Sitecore database. There was a buckets module which supported 6.3+ but appears to not be downloadable anymore: https://marketplace.sitecore.net/en/modules/sitecore_item_buckets.aspx. The code is out there though and possibly Sitecore support would even provide it.
The master database in a standard production environment (split content management and content delivery environments) if not accessible directly via connection string is made accessible by calling the Sitecore web API or creating a custom web service.
Requirements such as reporting and/or shared access to the data for other applications could possibly provide reasons to create a custom database but otherwise there is no reason not to store it in the master database.
You have to save the information filled by the user in Master database so that you can modify or use it using SItecore API.
Since the users filling the form may not have access to modify Sitecore Master DB. You would have to either switch the user to a user with least permissions required to make those changes(safer) or You would have to disable the security for a while and perform those tasks(not recommended). Both of these are explained in http://www.nehemiahj.com/2012/03/how-to-use-securitydisabler-and_15.html
And then add the form as an item in master db. If the number of form items created using this is more then use Sitecore Buckets.

Drupal: How to share content between two Drupal sites?

I have two drupal 7 sites and I want them to share content of a certain content type. I want to have this content stored in an external database. How could I make this happen with a custom module?
You can setup a Rest server.
Then you can use views to share the information you want.
Module: https://drupal.org/project/services
Maybe have a closer look on these modules:
Drupal Sync
Drupal Deploy
I didn't try out one of these so far, but I think it's what you are looking for.
Contents (ie. nodes) on a Drupal site are not stored in a single tables. The same tables are used to store content of different content type. Some of the tables are created dynamically when you add fields to a content type, or when you change their settings. So you cannot share some contents between two sites by simply sharing the table(s) used to store them.
As a rule of thumb, you cannot achieve anything complexe in Drupal by simply doing stuff at the database level. There is too much storage logic implemented in (PHP) code that cannot be ignored when accessing the DB. You should always base your solution on Drupal's API (and most of the time, not the DB layer API, but the high-level API such as the Node and Fields APIs).
That said, there is no core API to communicate between sites. I would use one of the site as the canonical source of the shared contents and the only site where they can be edited. Then somehow replicate these content on the second site. This can be done with the Services or RESTful Web Services module on the second site, and a custom module on the first site, used to push new contents and the updated contents to the second through a REST service.

Storing site specific configuration data

I have been given a job to re-develop a news portal. The website already has couple of thousands of unique visits a day. I am going to develop it using ASP.NET webforms. I am currently in the planning phase and I am thinking to offer the main admin a page where he can change site specific configuration information. Some of these are;
Web site title "<title>"
site URL
footer text
default image directory
whether to accept comments without authorisation or not
I listed above some settings so that you can understand my scenario better.
What I can't decide is, where to store all this information. Do I store them in a DB (costly?), a custom XML file? or a .config file. e.g. ConfigurationManager.AppSettings
Any pros or cons would make my day!
Thank you!
My opinion is to store them on web.config on WebConfigurationManager.OpenWebConfiguration().GetSection() because this variables are critical and change only ones - in the initialize of the site.
For example the default image directory is stay the same for the rest of the site life, the same and the site URL the same and the other.
Also when you change this settings probably you need also a restart of the web application because for sure you need to re-read them on some static variables.
And because this variables are stay as is, and need them for start the web (then you read the database and the rest) you need to have it in first hand, from the web.config.

Is it possible to dynamically modify role permissions and also generate the appropriate sitemap/menus in ASP.NET?

I'm doing some research on security and sitemaps in ASP.net and am unfortunately running short on time. I have not worked too much with ASP.net security so I'm not completely sure if I'm heading in the right direction.
Here is my problem:
I have a public website (i.e. on the internet) that will allow any user to sign up to. The website will be developed using ASP.net webforms. These users may create other users and assign these users different roles.
Different roles have different restrictions and the menu is displayed appropriately. For example, a user acting as an administrator can see all menu options. Whereas a limited user will only see some of these menu items.
There needs to be the ability for users on our end to modify what pages certain roles can access. For example, if Role1 can do task X, we would like to be able at some point modify Role1 to no longer do task X. This would be done using an application built in-house.
User types (roles) are to be saved in the database. User permissions (what pages each type can have access to) are also to be saved saved in the database.
Here is something I am thinking of doing:
Implement the authorization and authentication set up built in to ASP.net using the web.config file
Use Sitemaps to dynamically create menus/breadcrumbs from the database
I believe it is possible to do the second one using custom providers (please correct me if I'm wrong). But I am not entirely sure if it's possible to configure the web.config file dynamically.
I suppose this is really more of a yes/no answer but I would just like to make sure I'm not going in the wrong direction. I will be using VS2008 and .net 3.5 framework.
Many thanks.
Yes, it's possible to do what you're saying. You can dynamically create the sitemaps using a custom SiteMapProvider, see this articlet http://www.codeproject.com/KB/aspnet/dynamicsitemap.aspx.
You can also modify the web.config at runtime using an XmlReader or if you prefer, just reading it into a string and parsing out the authorization element. I'd put it in a separate file, though, using configSource:
<authorization configSource="auth.config" />
Then you only need to modify that file and not worry about messing up the web.config

Resources