简体   繁体   中英

Different url based on development environment with C# MVC

I have two MVC web applications, a www.company.com and a solution.company.com

The website www.company.com include links to solution.company.com/Contact but how can I set the href in the View to be able to test them in the development/pre-production/production environments?

Dev:

<a href="http://localhost:88/Contact/">Contact Us</a> 

QA:

<a href="http://qa.solution.company.com/Contact/">Contact Us</a> 

PRD:

<a href="http://solution.company.com/Contact/">Contact Us</a> 

You can use web.config to set different variables. Use separate web.config for each environment. Eg. web.release and web.debug. Same way you can use. Separate files for each environment

If you use, Octopus deployment. Use can set in octopus variables also.

<appSettings>
  <add key="MyVariable1" value="False" />
  <add key="MyName" value="akshay bheda" />
</appSetting>

Now you can easily access this variable and its value from your C# code:

string myVariable = System.Configuration.ConfigurationSettings.AppSettings["MyName"];

Now instead of writing url there, you can use this string instead.

<a href="<%= ConfigurationManager.AppSettings["someKey"] %>">

If you don't want to use Octopus Deployment, You can follow below steps.

1.) Create new Configuration from Configuration Manager. It is located under Build Menu. 配置管理器 and create a new configuration say for eg. Production and select Copy settings from Debug or any other present web.config so you don't have to write again.

2.) After creating a new configuration, Right click on Web.config and click Add Config Transformation Web.config设置 after that you will find your new configuration's web.config.

Make the changes in the appSettings section in each of your config and while starting the project, select your build configuration.

It will take the configuration settings from your appSettings section from that respective config.

Using an <appSettings> tag in web.config you can supports a file attribute that will load an external config with it's own set of key/values. These will override any settings you have in your web.config or add to them.

eg;

<appSettings file=".\EnvironmentSpecificConfigurations\dev.config">

<appSettings file=".\EnvironmentSpecificConfigurations\qa.config">

<appSettings file=".\EnvironmentSpecificConfigurations\prod.config">

Inside the .config file

  <appSettings>
    <add key="webaddress" value="yourwebsite.com"/>
  </appSettings>

Aspx Page

<a href="<%=ConfigurationManager.AppSettings["webAddress"]%>">L‌​ink</a>

If for some reason you do not have an automated deploy system that lets you specify per-environment variables (like Octopus as mentioned in previous answers) there are a couple of other options.

1: Put your settings in a machine.config file for each environment and deploy that config to the appropriate servers.

2: Put your relationships in your config file:

  <appSettings>
    <add key="contact-for-localhost" value="http://localhost:88/Contact/" />
    <add key="contact-for-qa.company.com" value="http://qa.solution.company.com/Contact/" />
    <add key="contact-for-www.company.com" value="http://solution.company.com/Contact/" />
    <add key="contact-for-company.com" value="http://solution.company.com/Contact/" />
  </appSettings>

then ask for the settings by hostname in your controller:

var contactLink = ConfigurationManager.AppSettings[$"contact-for{Request.Url.Host}"]

and pass it to your model.

As you don't have different configurations to switch between, to test this approach you can change your hosts file (c:\\System32\\drivers\\etc\\hosts) to fake being each of the environments

127.0.0.1  localhost
127.0.0.1  qa.company.com
127.0.0.1  company.com
127.0.0.1  www.company.com

Then comment out or remove the non-localhost entries to connect to the real servers.

From what you can see in the already existing answers, you're going to need to change your static string hrefs for something defined in compile time. I think you should follow the previous advises and write different tags for the Web.Debug.config and the Web.Release.config , but not to solve your specific situation, mostly to define your connection strings in case you have different database sources for each base.

To solve your specific situation, just use the Url native MVC helper, and replace your static hrefs for something like, <a href="@Url.Content("~/Contact")"> Contact </a> , where "~/" stands for your domain root, regardless of which one it is.

Also, given you didn't write any Controller name before "Contact", I'm assuming you have a ContactController in your application and is reaching its Index View with this address.

What if you made the Model for the MVC View a Dictionary or added a dictionary of settings to the Model returned and simply returned the data from the controller?

<a href="@Model["ContactUsUrl"]">Contact Us</a>

OR

<a href="@Model.Settings["ContactUsUrl"]">Contact Us</a>

Alternatively you could just use a Model that has a ContactUsUrl property

<a href="@Model.ContactUsUrl">Contact Us</a>

Then in your controller code you could use whatever logic you want to decide whether it is DEV, QA or PROD and pull the data for the URL from the associated source, eg a database, a config file, a custom settings file. This abstracts the logic and simplifies how your data is used on the page.

This is an alternative to using the web.config directly.

The solutions proposed are good but a lot of overhead just to switch one url IMHO.

I would take the environment variable approach and set the url accordingly.

Contact.cshtml

@{
    var env = Environment.GetEnvironmentVariable("MY_APP_ENV");
    var url = env == "prod" ? "http://qa.solution.company.com/Contact/" :
              env == "qa"   ? "http://solution.company.com/Contact/" :
                              "http://localhost:88/contact/";
}

<a href="@url">Contact Us</a>

If this is a big project and you can invest some time, I would put this in appSettings and set up parameters.xml for each environment and use it during deployment.

If you want to use DotNet Core or want to switch to it, then it is best to implement it's environment configuration abilities.

Documentation on official site: Working with multiple environments and Configuration in ASP.NET Core

Here is a good example.

var builder = new ConfigurationBuilder()
    SetBasePath(hostEnv.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{hostEnv.EnvironmentName}.json", optional: true, reloadOnChange: true);

All you need is to define 3 different appsettings files. And set ASPNETCORE_ENVIRONMENT in your system there you want to do your tests or developing.

Or you can use env.IsEnvironment("environmentname") to check something in runtime.

You don't need to use app settings for this. Just use the URLHelper that's part of MVC and it'll ensure that the correct hostname is used.

So instead of this:

<a href="http://solution.company.com/Contact/">Contact Us</a> 

You do this:

<a href="@Url.Action("Index", "Contact")">Contact Us</a>

That will generate a link that points to the Contact action within the IndexController .

Another option is to use the HTMLHelper extension method to generate the entire tag for you. In that case, you'd do this:

@Html.ActionLink("Index", "Contact", "Contact Us")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM