Best way to distinguish environment in MVC3? - asp.net

I am using MVC3, and I am wondering what is the best way to distinguish your environment? For instance I am thinking of adding a key to appSettings and referencing it, however in MVC3 is there a better way? I am working on 3 environments: Development, Staging, and Production.
Thanks

I use the configuration manager and define DEBUG, TEST, RELEASE as compile time constants. For configurations I use Web.config Transformation Syntax for Web Application Project Deployment and would highly recommend using them.
For example:
//web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="MyConnectionString"
connectionString="Data Source=SqlServer\Sql2008;
Initial Catalog=MyDB.Dev;
Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
<add key="SomeAppSetting"
value="DebugValue"/>
</configuration>
Test transformation:
//web.Test.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="MyConnectionString"
connectionString="Data Source=SqlServer\Sql2008;
Initial Catalog=MyDB.Test;
Integrated Security=SSPI"
providerName="System.Data.SqlClient"
xdt:Transform="SetAttributes"
xdt:Locator="Match(name)"/>
</connectionStrings>
<add key="SomeAppSetting"
value="TestValue"
xdt:Transform="SetAttributes"
xdt:Locator="Match(key)"/>
</configuration>
When I change my configuration from debug to test and rebuild/deploy my app now uses the transformation update in my web.Test.config. Extremely useful.
You can build different configurations using the Configuration Manager Dialog Box. At anytime you can right click on the web.config and select Add Config Transformations to have Visual Studio 2010 create the transformation config files automagically.

Web.config is probably a good place, for the MVC UI project. assuming that data layer and service layer are separated you would also have entries in those other projects.

I would recommend taking a look at web config transformation. Once you have the basis of your web.config setup you would create a transformation for your staging and production environments.
Many good examples on the net if you require more info.

Related

What does <clear /> signify when specifying a connectionstring?

This answer to another question states:
Do not forget to clear the connectionStrings first:
<connectionStrings>
<clear />
<add name="LocalSqlServer" connectionString="Data Source=(local);Initial Catalog=aspnetdb;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
... interesting. What does that do?
In .Net config files are inherited, so your applications config will inherit settings from your machines config.
The <clear/> tag will remove any inherited connection strings and thereby avoids confusion and potential problems.
In ASP.Net you may have several inherited connection strings, so this is very common there.
The element removes all sections and section groups from your application that were defined earlier in the current configuration file or at a higher level in the configuration file hierarchy.
http://msdn.microsoft.com/en-us/library/aa903345(v=vs.71).aspx
so for example, if this was a child config file and the parent config file had some settings... you may not want them being inherited so you specify the clear flag to clear it and then use your settings.

Web.Debug.config not processing substitution

I have a web application in VS2010 with a web.config like this:
...
<configuration>
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=MyProdDb;Initial Catalog=MyCat;User Id=MyUser;Password=MyPass;"
providerName="System.Data.SqlClient" />
</connectionStrings>
...
and a Web.Debug.config like this:
...
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="ApplicationServices"
connectionString="data source=MyDevDb;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
...
The project is set to create a Debug build, and when I run it in the debugger, I get MyProdDb rather than MyDevDb
What am I missing?
UPDATED INFORMATION
Arbitrary XML-based .config files can now be processed, and the processing can happen at build time rather than at deployment time
http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx
Brilliantly, the transforms can also be previewed directly in Visual Studio.
As people have said the web.config versions only get applied at publish (MSDeploy) time. The normal way you would do things is to have your 'Debug' config in the actual web.config file and make changes to that for each of the deployment scenarios you have.
What am I missing?
You are missing the fact that web.config transformation occurs only when you do a deployment. If you don't publish your web application you cannot expect any transformation to occur. If you just run your website locally by hitting F5 no transformation will occur. It's only when you publish the application that the transformation is performed.
Web.config transformations gets processed at publish time only. When debugging (even in release mode), the basic Web.config file is being used.

asp.net change value of a web.config item?

im trying to get role provider working in multiple environments and hitting a wall
(link text)
i should be able to dynamically set the connectionString property of the web.congig item on app_onstart to the correct DB conection String to get it to work...
can anyone show me how to dynamically alter items in the web.config?
im guessing reflection...
<roleManager enabled="true" defaultProvider="SqlRoleManager">
<providers>
<clear/>
<add name="SqlRoleManager" type="System.Web.Security.SqlRoleProvider" connectionStringName="ISConnectionString_prod" applicationName="IS"/>
</providers>
</roleManager>
i want to adjust the connectionStringName value in the above snipet
thanks
If you're using VS2010, you can get it to automatically apply transforms to your config files depending on which environment you're publishing to.
We use this to set connection strings, payment provider config settings (sandbox mode, username, etc.) and a couple of other things like how exceptions are handled.
If you're not publishing, you can actually hook these transforms straight into the build engine by editing the project file.
This makes it incredibly simple to maintain (You have a web.config and a web.Live.config which contains the transforms). It also makes the whole process far less error-prone
eg:
web.config
<connectionStrings>
<clear />
<add name="OurConnectionString" connectionString="Data Source=DevDbHostname;Initial Catalog=DevDb;user id=Username;password=Password;MultipleActiveResultSets=True" />
</connectionStrings>
web.Release.config
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="OurConnectionString"
connectionString="Data Source=LiveDbHostname;Initial Catalog=LiveDb;user id=Username;password=Password;MultipleActiveResultSets=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
</configuration>
As long as the permissions allow it (you will have to change them), you can treat the web.config just as any other XML file. Knowing that, you can simply use an XDocument and pop in a new XElement where you want it. But be very careful and be sure to save some backups!

ASP.NET Sql Provider

I got a problem. When i'm creating the new project in ASP.NET using VS 2010, it's web.config with a default connection string about SQL Express created. But i haven't even got SQL Express installed. What should i do to change the default AspNetSqlProvider to work with my instance of full-weight SQL Server as a services database? And how can i change the template for the ASP.NET project to create a project with my connection?
You mean this one:
<add name="ApplicationServices"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
To change this into one that'll work with SQL Server, it needs to look more like this:
<add name="ApplicationServices"
connectionString="data source=ServerName;Initial Catalog=DatabaseName"
providerName="System.Data.SqlClient" />
where DatabaseName is probably aspnetdb. It'll need some form of authentication, whether you use Windows authentication (in which case you can copy the Integrated Security element from the original connection string) or SQL Server authentication (where you'll have a username/password combination).
There's great info on building connection strings at connectionstrings.com.
To fix this for your future projects, you'll need to change the template for Web Projects. Locate the folder where your C# Web templates are kept (for me this is C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Web\1033.
Take a copy of the WebApplicationProject40.zip file (you might also want to backup the original somewhere!).
Inside it you'll find the web.config file with the SQL Express connection string. Change it to a SQL Server string, and then re-assemble the zip file.
The last step is to rebuild the VS template cache - from a command-line (VS Command Prompt probably works best), run devenv /installvstemplates. See here for details.
I just had a similar problem. I had a web site created in VS 2008 and wanted to try web parts. Added some to a page, then started getting:
SQLExpress database file auto-creation error:
The connection string specifies a local Sql Server Express instance using a database >location within the applications App_Data directory.
I ran aspnet_regsql.exe (wizard, in .Net framework folder) to create the database and then I added a connection string to web.config:
<configuration>
<connectionStrings>
<add name="aspnet_membership" connectionString="Data Source=localhost; Initial Catalog=aspnetdb; Integrated Security=SSPI;"/>
</connectionStrings>
</configuration>
Then I added this to web.config:
<configuration>
<system.web>
<webParts>
<personalization defaultProvider="SqlPersonalizationProvider">
<providers>
<add name="SqlPersonalizationProvider"
type="System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider"
connectionStringName="aspnet_membership"
applicationName="/" />
</providers>
<authorization>
<deny users="*" verbs="enterSharedScope" />
<allow users="*" verbs="modifyState" />
</authorization>
</personalization>
</webParts>
</system.web>
</configuration>

What i s best practice for accessing settings from config?

I want to know what best practice is for accessing settings
in config file when you have dev/test/production types.
If you have different config for each type when you
publish a ASP.NET website doesn't the config get copied as well??
Malcolm
We usually manually inject the settings file on each site. I think that it's uncommon, though not unheard of, to actually rely on VS to publish to your production site. Source control has dev/test/prod/ etc. web.config files.
ConfigurationManager.AppSettings ?
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.appsettings.aspx
In Visual Studio 2010 you can maintain Multiple Web.Config and use a transformation to generate the correct Configuration for an environment.
http://blogs.msdn.com/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx
Basically we can make have one default Web.Config and different Transformation files for each environment e.g.
Web.Debug.Config
Web.Staging.Config
Web.Production.Config
The Transformation file can override the value of a particular config item for the environment e.g.
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="personalDB"
connectionString="Server=StagingBox; Database=personal; User Id=admin; password=StagingPersonalPassword"
providerName="System.Data.SqlClient" xdt:Transform="Replace" xdt:Locator="Match(name)" />
<add name="professionalDB"
connectionString="Server=StagingBox; Database=professional; User Id=professional; password=StagingProfessionalPassword"
providerName="System.Data.SqlClient" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
</connectionStrings>
</configuration>
Whenever we target build for that environment the Transformation are applied to the default Web.Config file.

Resources