Use different connection string based on the application url in .net - c#

I have a asp.net web project named FinanceTracker (which is under use for an year).
And the data is stored in Finance_Tracker_db.
(this is a intranet web site to track the financial data for an organization, accessed from
http://OrgTracker)
Now I have a requirement to have the same application for IT department.
everything is same on the data for both should be segregated.
So I created an empty copy of database name IT_Tracker_db.(on same database server)
And used the old code with modified connection string in web.config
(accessed from http://OrgTracker/IT/ deployed on same IIS server)
But as to have less maintenance to apply the same code to both deployed version, I am planning to use the same code with different connection strings.
Now I wish to have something like.
http://OrgTracker/ - This should show two links
http://OrgTracker/fincance/
http://OrgTracker/IT/
And based on user selected URL the proper connection string should be used from web.config
Like all pages will remain same like.
http://OrgTracker/fincance/Status.aspx, http://OrgTracker/fincance/Inbox.aspx, etc.
http://OrgTracker/IT/Status.aspx, http://OrgTracker/IT/Inbox.aspx, etc.

Can have more than one config
ASP.NET Configuration File Hierarchy and Inheritance

I suggest not doing this. First, it is complicated and out of build-in ASP.NET functionality.
Second, in some time in future your users can demand different things: one department would want newer version immediately, while the other one would want to have stable old version until they can test everything.
P.S. But if I were you, I'd start thinking about adding additional column called "Department" in all relevant tables so I could unite databases in future. This goes against my second point :), but it would make everything more manageable and architecturally sound, especially if more departments would want to use your application.

Related

What's the best way to reuse database access across multiple projects to ensure that when updated it does not break any projects?

I have probably written the same LINQ to SQL statement 4-5 times across multiple projects. I don't even want to have to paste it. We use DBML files combined with Repository classes. I would like to share the same Library across multiple projects, but I also want to easily update it and ensure it doesn't break any of the projects. What is a good way to do this? It is OK if I have to change my approach, I do not need to be married to LINQ to SQL and DBML.
We have both console apps and MVC web apps accessing the database with their own flavor of the DBML, and there have been times when a major DB update has broken them.
Also, since currently each project accesses the DB from itself, which is sometimes on another server, etc. Would it be possible to eliminate the DB layer from being within each project all together? It might help the problem above and be better for security and data integrity if I could manage all the database access through a centralized application that my other applications could use directly rather than calling the database directly.
Any ideas?
The way I handle this is using WCF Data Services. I have my data models and services in one project and host this on IIS. My other projects (whatever they may be) simply add a service reference to the URI and then access data it needs over the wire. My database stuff happens all on the service, my individual projects don't touch the database at all - they don't even know a database exists.
It's working out pretty well but there are a few "gotchas" with WCF. You can even create "WebGet" methods to expose commonly used methods via the service.
Let me know if you want to see some example code :-)

What to keep in mind when developing a multi-tenant asp.net MVC application?

Good afternoon - I have a pretty general question today - I've been tasked with creating a web application to manage some basic information on customers. It's a very simple application, but what I don't know is what to keep in mind to develop the site around supporting multiple users at their own domains or subdomains of our url?
How would I restrict users from logging in to each others portion of the app?
I've seen mention of database scoping in similar questions on Stack Overflow, could anybody elaborate on best practices for an implementation like this?
Are there any new features in MVC3 to support multi-tenancy? I am facing this issue with MVC2 and my eCommerce site where we decided we wanted it white-labeled and customizable for multiple shop owners, and don't know where to begin in implementing these features in an existing application. Any input is appreciated.
edit
To elaborate on multi-tenancy, what I mean - in the context of a store for example, multiple users sign up for their own store at www.mystore.com and are each given a unique subdomain to access their own instance of the store, at user1.mystore.com, user2.mystore.com etc. Each store would have customers with order histories, and those customers would have logins. I would need to restrict customers of user1.mystore.com from logging in at user2.mystore.com without a new account, and likewise prevent user2.mystore.com from accessing user1.mystore.com's customer history.
I implemented a complete MVC multi-tennant app. Here are some links I found handy and some sample apps:
http://msdn.microsoft.com/en-us/library/aa479086.aspx
http://codeofrob.com/archive/2010/02/14/multi-tenancy-in-asp.net-mvc-controller-actions-part-i.aspx
http://www.developer.com/design/article.php/10925_3801931_2/Introduction-to-Multi-Tenant-Architecture.htm
http://msdn.microsoft.com/en-us/library/aa479086.aspx#mlttntda_cc
http://lukesampson.com/post/303245177/subdomains-for-a-single-application-with-asp-net-mvc
http://code.google.com/p/multimvc/
http://www.paulstovell.com/widgets
http://www.agileatwork.com/bolt-on-multi-tenancy-in-asp-net-mvc-with-unity-and-nhibernate/
http://ayende.com/blog/3530/multi-tenancy-approaches-and-applicability
http://weblogs.asp.net/zowens/archive/tags/Multi-tenancy/default.aspx
http://cloudsamurai.codeplex.com/
http://cloudninja.codeplex.com/
http://msdn.microsoft.com/en-us/library/hh534484.aspx
http://blog.maartenballiauw.be/post/2009/05/20/ASPNET-MVC-Domain-Routing.aspx
http://blog.tonywilliams.me.uk/asp-net-mvc-2-routing-subdomains-to-areas
Even starting from scratch, you are in for a world of hurt. The MVC framework does very little to help you address the issues.
Most likely you are about to spend a fair amount of time restructuring your database.
The first step is that you are going to create a table to house your "Tenant" list. Then you need to add this TenantId to just about every table in your system to make sure no one steps on each other. You can skip any tables that are global in nature. One example might be a list of Status Codes.
However, everything from users to the data they have etc will have to have this ID. Also, modify all of your indexes to take tenantid into account.
Once you have that, you'll need to modify all of your queries to take the tenantid into account.
One column of the tenants table should be the portal url. Like customername.oursite.com or whatever. This way you could point multiple urls to the exact same code. When the site needs to use the current tenantid just look it up based on the URL the passed in.
If I was doing this, I'd plan to spend about 1 to 2 hours per table in the database to make it "multi-tenant". Obviously some tables (and their queries) will go faster; others will take longer.
Incidentally, this doesn't cover things like customizing the UI (look / feel) per tenant or anything of that nature. If you need to do this then you'll have to either create a directory on the server for each tenant to hold their style sheets or load it directly from the DB (which has it's own issues with regards to caching).
Typically, you design for this at the beginning of the project. Refitting an already (or almost) complete project is a PITA.
Finally, test, test, test and do more testing. You will have to make sure that every single query pulls only the data it absolutely needs to.
There has been some talk of multi-tenancy support in Sharp Architecture (based on MVC 3) found here: http://www.yellowfeather.co.uk/2011/02/multi-tenancy-on-sharp-architecture-revisited/
Not sure if that really helps you with your existing application, porting over would be a bit of a job.

websites for different regions

I have got a requirement from a client. They need three blogging web application for three different regions. Each application have its own data and posts. Probably they want to share user information between these applications. User interface of these application will be same except css level changes (color, font and styles) and little bit layout changes in home page for each blog. That brought lot of questions to my mind.
Three seperate site approah
1. Is that good to develop three different websites for each region and deploy them in three subdomains?
2. Am I going to use same database or individual database for each region?
3. If there are three web sites, how am I going to overcome caching, session sharing and user signon(single sign-on), multiple deployment, duplication of code issue?
Single Site Approach
1. Create a single site, seperate the regions like sitename/regionname?
2. If it is single site, how the performance and scalability is going to be?
3. Just use singe database, that would be shared between three regions. Is that good approach?
There could be many more possiblities. Now I need your guidance that what are all other unknown problems would occur and how would I approach this problem one by one and come to a conclusion that which is best?
We may implement this solution in C#.
EDIT: The sites will be in English language
You have a lot of choices to make here, so you need to get some good information from the client.
You mention that there will be layout changes between the sites. This part right here says that you might be better off with three different sites for the user interface. It's probably a good assumption that they are going to want to change the UI's to each site on an individualized basis. Building all of that into a single engine is difficult.
All three could share a single database, you just need to make sure that each post, config piece, etc all have a SiteId associated with them. Also you'll need to make sure that every query you write uses that SiteId value. This situation is called a Multi Tenant architecture.
Caching will be handled just like caching for a single site.
After writing all of this, it occurs to me that you might be better served by simply taking an existing product like WordPress or something similar and creating templates for it for your purposes.
I've had a similar design-issue recently, so let me share with you my approach (however wrong or right you think it is!). I went with a single site, single database coupled with host headers.
The first thing I did was to create a domain table. It kind of looked like this:
_domains:
_id INT IDENTITY NOT NULL
_domain_name NVARCHAR(255) NOT NULL
_id_category_root INT NOT NULL (foreign key to _categories::_id)
This allowed me to specify a top-level domain for content categories. Content categories belonged to the domains.
_categories:
_id INT IDENTITY NOT NULL
_category_name NVARCHAR(64) NOT NULL
_id_parent INT NULL (foreign key to _categories::_id)
_theme_root NVARCHAR(64) NOT NULL
The _theme_root field specified the default theme folder within the root. This allows each category to (optionally) have a different css and, if it so desires, a different master page. This allows content categories to look completely different (CSS, images and layout) or even just the CSS using the default master page.
And, thusly, content belonged to a category:
_id INT IDENTITY NOT NULL
_id_category INT NOT NULL (foreign key to _categories::_id)
_content_title
-- other fields
I abstracted it this way because you can have multiple domains for the same category level:
enGB.mysite.com -> category 1
www.enGB.mysite.com -> category 1
frFR.mysite.com -> category 2
etc
In my code, I look at the host header and pick the category appropriately, serving content and other tables that branch of that made category table. If the host header does not match, I fall back on a default (The english site).
EDIT: Added notes on theming.
It is not good to develop 3 different web sites. The maintenance will quickly become a nightmare and the code will be very cumbersome.
Break it down into Services (SOA) Service Oriented Architecture. This is language agnostic. So if you use C#, PHP, Java, or Python the general idea is the same.
1.) Create a User Service to authenticate users.
2.) Create a Blog Service to handle storing, retrieving, and editing blogs.
3.) Create a single site to communicate with the services and use localization.
Using a service has the added benefit of being able to change the database design, DBMS, etc... without having to change the core application.
In the User Service store some kind of local identifier so that your single site can change based on localization rules. All the major languages have localization settings to do most of the work for you such as date format, currency, etc...
Note: It is best to get the Region name during the User Registration - not the Sign-In.
A design like the one described above makes the code much easier to maintain - compared to 3 separate sites.
It should be a single site, and it should be a single database. Scalability is a whole other issue of it's own. What kind of traffic are you expecting?
Anyways, take a look at nvidia.com, this site is setup for different regions across the world. It's still all the same website in most cases. Some parts may be hosted in different countries, but they are probably connecting to the same database or set of synced databases.
The other most important thing, is do you want all the sites to be exactly the same but just in a different language? If so this will just be simple text replacement, or your database would just be setup to where your application can easily switch out content from different languages.
Your project certainly needs a lot of time in the planning stages. You need to make sure you know exactly what your client needs because that can often be different from what they want. Plan some options for your client and present the pros and cons of these options. Then let them decide.
There may be a single site... and with that single site u can also use it with different url ...
My Mean to say website is a single and all users uses this site with different url so they fell that they have their own site .. but actually there is only one site.....with one database ....
its possible .. and its a best way .....

Web App Configuration Settings - Best Practices

I was recently involved with patching a web app project and noticed the previous developer used database table for configuration settings instead of web.config (app.settings).
Which should I use? web.config or database table? Which is best?
Things should go into the web.config in the following situations:
They're things that must be available to make the database available (db connection string!)
They're things that, if they should change, you want the application pool to refresh, or that are insanely unlikely to change.
They're things that need to be available when the database is unavailable for any reason (such as a list of email addresses and an smtp server to send error messages to, or locations where log files belong)
Things should go into the database in the following situations:
Both your DB and your web layer use that configuration.
You need the ability to change the configuration on the fly, without forcing an application pool refresh.
That said - if you're going to put your config in the database you probably want to cache it in some way in the web layer so you're not hitting the db unnecessarily. I suggest the Cache class for this.
In addition to all of the above, you will also need to consider your company's policy for working with your servers. If its very, very hard for you to work with the db, it might make more sense to put things in the web.config and vice versa.
One advantage for using a database for the settings is that things can be changed on the fly without disrupting the production website.
Changes to the web.config file will cause the worker processes on IIS to recycle and the app to be re-started. If you are using InProcess sessions, those will be lost. This could potentially disrupt your website users.
We use a combination of both web.config settings and database level settings.
For each setting we ask the following question: "Is this setting specific to the machine that the application is running in?" If it is, then it goes in the web.config. If not, then we ask an additional question: "If this setting is changed, should the app be forced to reboot?" If yes, web.config. More often than not a reboot is not acceptable for our service level agreements.
Most of our applications are multi-tenant and/or run in a web farm. Simple things like a local file system path, logging level, or database connection strings go in the web.config. The reason is that these deal with resources specific to that machine.
Pretty much everything else is going to impact program execution and must be accessible to both the app and data layers. Also, they tend to be needed by other applications (assuming multiple applications hit the same database).
It it makes sense why the prev. dev used the DB for setting, go with it. You must have a web.config, I think an ASP.NET can't work without it. Project configuration setting should go into web.config (declarations of custom controls, additional assemblies etc...), but user settings or anything specific about the business logic may be better off in the database.
A contentious issue between developers and DBAs at my company.
In my opinion you should always use configuration files for application level, read-only settings. If the settings are user specific or editable at runtime you may or may not want to reconsider the approach.
I have seen situations where settings are stored in the database that are used internally within stored procedures. I can see some justification for this, but it’s not critical since the value can be passed to the procedures via a parameter.
One consideration may be that once the web application is deployed, the developer no longer had access to the web.config files in the production environment.
If he's occasionally needing to view settings to provide any form of support, putting settings in a database where he can get read-only access to a configuration table may make tons of sense.
One use case that argues for a database is load-balanced applications, like web farms. There may be some settings that are relevant to a single machine distinct from the other machines in the farm, that need to go in the web.config, but there will probably be a whole slew of settings that are supposed to be identical across the farm. The farm is supposed to look like a single application from the outside, and can benefit if it can be configured like a single machine. That means some sort of shared repository, like a database.

Data-Driven Websites for Very Small Businesses

I have a client who has a product-based website with hundreds of static product pages that are generated by Microsoft Access reports and pushed up to the ISP via FTP (it is an old design). We are thinking about getting a little more sophisticated and creating a data-driven website, probably using ASP.NET MVC.
Here's my question. Since this is a very small business (a handful of employees), I'd like to avoid enterprise patterns like web services if I can. How does one push updated product information to the website, batch-style? In a SQL Server environment, you can't just push up a new copy of the database, can you?
Clarification: The client already has a system at his facility where he keeps all of his product information and specifications. I would like to refresh the database at the ISP with this information.
You don't mention what exactly the data source is, but the implication is that it's not already in SQL Server. If that's the case, have a look at SSIS.
If the source data is in SQL Server, then I think you'd want to be looking at either transactional replication or log shipping to sync the two databases.
If you are modernizing, and it is a handful of employees, why would you push the product info out batch style?
I don't know exactly what you mean by "data driven", but why not allow the ASP.NET app to query the SQL Server product catalog database directly? Why generate static pages at all?
UPDATE: ok, I see, the real question is, how to update the SQL database running at the ISP.
You create an admin panel so the client can edit the data directly on the server. It is perfectly reasonable to have the client keep all their records on the server as long as the server is backed up nightly. Many cloud and virtual services offer easy ways to do replicated backups.
The additional benefit of this model is that more than one user can be adding or updating records at a time, making the workforce a lot more scalable. Likewise, the users can log in from anywhere they have a web browser to add new records, fix mistakes made in old records, etc.
EDIT: This approach assumes you can convince the client to abandon their current data entry system in favor of a centralized web-based management panel. Even if this isn't the case, the SQL database can be hosted on the server and the client's application could be made to talk to that so you're only ever using one database. From the sounds of it, it's a set of Access forms and macros which you should have source access to.
Assuming that there is no way to sync the data directly between your legacy system DB (is it in Access, or is Access just running the reports) and the SQL Server DB on the website (I'm not aware of any):
The problem with "pushing" the data directly into the SQL server will be that "old" (already in the DB) records won't be updated, but instead removed and then recreated. This is a big problem with foreign keys. Plus, I really don't like the idea of giving the client any access to the db at all.
So considering that, I find that the best is to write a relatively simple page that takes an uploaded file and updates the database. The file will likely be CSV, possibly XML. After a few iterations of writing these pages over the years, here's what I've come up with:
Show file upload box.
On next page load, save file to temp location
Loop through each line (element in XML) and validate all the data. Foreign keys, especially, but also business validations. You can also validate that the header row exists, etc. Don't update the database.
3a. If invalid data exists, save an error message to an array
At the end of the looping, show the view.
4a. If there were errors, show the list of error messages and tell them to re-upload the file.
4b. If there were no errors, create a link that has the file location from #2 and a confirmation flag
After the file location and confirm flag have been submitted run the loop in #3 again, but there's an if (confirmed) {} statement that actually makes the updates to the db.
EDIT: I saw your other post. One of the assumptions I made is that the databases won't be the same. ie, the legacy app will have a table or two. Maybe just products. But the new app will have orders, products, categories, etc, etc. This will complicate "just uploading the file".
Why do you need to push anything?
You just need to create a product management portion of the webpage and a secondly a public facing portion of the webpage. Both portions would touch the same SqlServer database.
.Net has the ability to monitor a database and check for updates. then you can run a query to [push] the data elsewhere.
or use sql to push the data with a trigger on the table(s) in question.
Is this what you were looking for?
You can try Dynamic Data Web Application.
You should have a service that regularly updates the data in the target DB. It will probably run on your source data machine (where the Access-DB is)
The service can use SSIS or ADO.NET to write the data. You can do this over the web, because you have access via TCP/IP to the server I assume.
Please check when the updates are done and how long it takes. If you can do the updates during the night you are fine. If not you should check, if you can still access the web during the import. That is sometimes not the case.
Use wget to push the new data file to the mvc app and once the data is received by the action, the mvc app invokes the processing/importing of the data (maybe in a worker process if you dont want long requests).

Categories