VS2012 changes my IIS Express configuration file detrimentally when opening solution - visual-studio-2012

Given the following site, configured within applicationHost.config for IIS Express 7.5
<site name="MySite" id="1">
<application path="/" applicationPool="Clr2IntegratedAppPool">
<virtualDirectory path="/" physicalPath="path\to\the\site" />
<virtualDirectory path="/VDir1" physicalPath="path\to\the\site" />
<virtualDirectory path="/VDir2" physicalPath="path\to\the\site" />
<virtualDirectory path="/VDir3" physicalPath="path\to\the\site" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:12345:localhost" />
</bindings>
</site>
When opening this solution, from Source Control Explorer (TFS2010) using VS2012 - the act of opening the solution changes the XML structure so that each virtualDirectory node lives inside it's own application node (which VS2012 creates for me)
As this is a legacy .NET 2.0 application, which in it's wisdom, references controls, files, etc across the virtual directories shown above - as soon as they are given their own application in the config file any calls from / to /VDir1 or /VDir1 to /VDir3 (for example) fail with the error "The virtual path X maps to another application, which is not allowed"
I have no problem with that error and it's validity, but does anybody know how I can stop VS2012 from meddling with my config file.
Couple of other points
applicationHost.config is source controlled (trivial)
Solutions in question are set to "Use IIS Express" with the configuration settings such as hostname, port set inside the project properties.

Related

In IIS 8.5 is there a way of setting the ConnectionTimeout limit in web.config?

In IIS 8.5 is there a way of setting the ConnectionTimeout limit in web.config?
I can see how you would set this at the Website level (either through the IIS Manager GUI or via settings https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/sitedefaults/limits) but would like to set it at the application level i.e. via web.config if possible.
I am aware of the web.config executionTimeout setting (i.e. httpRuntime executionTimeout="100"): and so was hoping there might be something similar for connectionTimeout.
You can set per site limits from applicationHost.config, which would look like this:
<sites>
<site name="Default Web Site" id="1" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/"
physicalPath="%SystemDrive%\inetpub\wwwroot" />
</application>
<bindings>
<binding protocol="http"
bindingInformation="*:80:" />
</bindings>
<limits maxBandwidth="65536"
maxConnections="1024"
connectionTimeout="00:01:00" />
</site>
</sites>
(example taken from Microsoft docs)
If you execute the below appcmd during deployment you would get the same effect, but you cant use web.config to manage this value.
appcmd.exe set config -section:system.applicationHost/sites "/[name='Default Web Site'].limits.connectionTimeout:00:01:00" /commit:apphost
I would strongly suggest using appcmd.exe to update these values rather than editing the XML directly (the 32 or 64 "bit-ness" of your editor makes a difference!).
These settings are managed by the applicationhost.config file. so you have to manually change it. and it is not a recommended way to modify the applicationhost file manually. it may break your other configuration.
you could use iis manager GUI or you can use the below commands:
appcmd.exe set config -section:system.applicationHost/sites /[name='sitename'].limits.connectionTimeout:"00:03:00" /commit:apphost
or
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -filter "system.applicationHost/sites/site[#name='testiis']/limits" -name "connectionTimeout" -value "00:03:00"

ASP.NET 5 web application as Azure Web Role?

We have a ASP.NET 5 web application in our solution.
Typically, we could right click on the Cloud Service "Roles" item and add a new role from an existing project in the solution.
But it cannot identity this project as a Web Role:
How are we able to host a ASP.NET 5 project in a Azure Web Role?
Edit: We are using Azure SDK 2.7
Sorry, we don't support WebRoles at the moment. You might* be able to hack your way around but officially there is no support. That means that any hack you do, will be in a text editor, not from tooling.
However, you can use an Azure WebSite instead. That's fully supported.
* it might not work at all. I am not aware of anyone who did this.
You probably have to build your package yourself using CSPack. Here an example using PowerShell and CSPack:
# path to cspack
$cspackPath = Join-Path $env:ProgramFiles 'Microsoft SDKs\Azure\.NET SDK\v2.7\bin\cspack.exe'
$PackagePath = 'c:\mycloudpackage.cspkg'
$serviceDefinitionFile = 'c:\myProject\ServiceDefinition.csdef'
$webRoleName = 'MyWebRole'
$webRolePath = 'c:\myProject'
$webRoleEntryPoint = 'MyWebRole.dll'
# define the cspack parameters
$cspackParameter = #(
"/out:$PackagePath",
$serviceDefinitionFile,
"/role:$webRoleName;$webRolePath;$webRoleEntryPoint",
"/sites:$webRoleName;Web;$webRolePath"
)
# execute cspack
& $cspackExe #cspackParameter
It also allows you to host multiple sites on a single web role.
Edit: Cannot be done with Azure Storage Emulator...
I really struggled with this as I found the documentation seriously poor with no proper examples, so here's a full example of my scripts and files for anyone else, based on Martin Brandl's answer.
You do not need webRoleEntryPoint for only a web role. Only used for worker roles.
Create a new empty cloud service in your project. This will generate emptyServiceConfigiguration.Cloud.csfg, ServiceConfigiguration.Cloud.csfg and ServiceDefinition.csdef files for you as well as an empty roles folder. You could also add a web/worker role to let visual studio generate the configuration in them and then just modify them accordingly.
Modify these files (change the physicalDirectory to your own):
ServiceDefinition.csdef:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="SoundVast.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
<WebRole name="WebRole1" vmsize="Small">
<Sites>
<Site name="Web" physicalDirectory="../SoundVast">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
</Bindings>
</Site>
</Sites>
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
</ConfigurationSettings>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>
</WebRole>
</ServiceDefinition>
<Site name="Web" physicalDirectory="../SoundVast"> is the important line, this physicalDirectory is relative to wherever your .csdef file is located and I wanted to make my main project SoundVast the web role which was located one level up.
ServiceConfiguration.Cloud.csfg and ServiceConfiguration.Local.csfg (both can be the same):
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="SoundVast.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="4" osVersion="*" schemaVersion="2015-04.2.6">
<Role name="WebRole1">
<Instances count="1" />
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="UseDevelopmentStorage=true" />
</ConfigurationSettings>
</Role>
</ServiceConfiguration>
The important part is that the role name matches your <Role name="WebRole1"> service definition files web role name.
# path to cspack
$cspackPath = Join-Path $env:ProgramFiles 'Microsoft SDKs\Azure\.NET SDK\v2.8\bin\cspack.exe'
$PackagePath = 'C:\Users\Yamo\Documents\visual studio 2015\Projects\SoundVast\SoundVast.Azure\SoundVast.cspkg'
$serviceDefinitionFile = 'C:\Users\Yamo\Documents\visual studio 2015\Projects\SoundVast\SoundVast.Azure\ServiceDefinition.csdef'
$webRoleName = 'WebRole1'
$webRolePath = 'C:\Users\Yamo\Documents\visual studio 2015\Projects\SoundVast\SoundVast.Azure'
# define the cspack parameters
$cspackParameter = #(
$serviceDefinitionFile,
"/role:$webRoleName;$webRolePath;",
"/sites:$webRoleName;SoundVast;$webRolePath",
"/out:$PackagePath"
)
# execute cspack
& $cspackPath #cspackParameter
A .cspkg file should now have been generated at the location of your $PackagePath.
I've just blogged on how to do this (with VS tooling support!) here: https://oren.codes/2017/10/16/using-asp-net-core-with-azure-cloud-services/
It appears that it isn't officially supported as a web role at this time. It seems that it is only compatible with the web apps and not the older web role. The current work around is documented on this site:
http://www.codeproject.com/Articles/331425/Running-an-EXE-in-a-WebRole-on-Windows-Azure

Cannot access RoleEnviroment when running multiple Sites inside Cloud Service

I have got an existing solution which uses settings from RoleEnviroment in both the WebRole.OnStart and Global.asax Application_Start handlers. (This has been running well for months)
This all works fine when I have just one Site inside my role:
<WebRole name="WebRole" vmsize="ExtraSmall">
<Runtime executionContext="elevated" />
<Sites>
<Site name="Web1" physicalDirectory="..\..\..\Web1\">
<Bindings>
<Binding name="HTTP" endpointName="Public HTTP" hostHeader="web1.com" />
</Bindings>
</Site>
</Sites>
However when I add my second site, neither site can access RoleEnviroment??
<WebRole name="WebRole" vmsize="ExtraSmall">
<Runtime executionContext="elevated" />
<Sites>
<Site name="Web1" physicalDirectory="..\..\..\Web1\">
<Bindings>
<Binding name="HTTP" endpointName="Public HTTP" hostHeader="web1.com" />
</Bindings>
</Site>
<Site name="Web2" physicalDirectory="..\..\..\Web2\">
<Bindings>
<Binding name="HTTP" endpointName="Public HTTP" hostHeader="web2.com" />
</Bindings>
</Site>
</Sites>
I have tested this in the local azure emulator (full) and it works fine, but when deployed to an actual web role it throws:
[SEHException (0x80004005): External component has thrown an exception.]
RdGetApplicationConfigurationSetting(UInt16* , UInt16** ) +0
RoleEnvironmentGetConfigurationSettingValueW(UInt16* pszName, UInt16* pszDest, UInt64 cchDest, UInt64* pcchRequiredDestSize) +73
Microsoft.WindowsAzure.ServiceRuntime.Internal.InteropRoleManager.GetConfigurationSetting(String name, String& ret) +133
Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(String configurationSettingName) +109
Web1.Installer.Install(IWindsorContainer container, IConfigurationStore store) in c:\projects\Webs\Web1\Installer.cs:21
I have checked that the setting I am trying to access is there. When I remove the second Site it works fine. When I remove the first Site it also works fine. It looks to me like there is an issue with Azure providing access to the RoleEnviroment for web roles in multiple instances.
Okay, so after working on this for almost 2 days. The issue turned out to be mismatching Azure SDK version assemblies on the projects.
The older Site had Azure SDK 2.4, and for some reason the newer Site had SDK 2.3, this meant the RoleEnvironment could not be found when there was two sites (both version of the assembly) deployed.
I assume this is because they are looking for the RoleEnvironment differently, or are conflicting in how they access it.
I've read that this may be related to the 'Rd' environment variables that may cause RoleEnvironment to be IsAvailable = false.
So guys: Check your Azure SDK assembly versions are sync if you encounter this issue!

Images from outside wwwroot not displaying (despite mapping)

In my ColdFusion application, I want to keep the images outside of wwwroot in this folder: C:\extSite\stdImages
I created a mapping in wwwroot\WEB-INF\jrun-web.xml like this:
<virtual-mapping>
<resource-path>/extStdImages</resource-path>
<system-path>C:\extSite\stdImages\</system-path>
</virtual-mapping>
To display an image, I do this:
<img src="/extStdImages/abc.jpg">
This works fine on my dev site (which is using ColdFusion's built-in web server), but the image does not display in production (where I am using IIS). I am wondering if I have to tweak something in IIS or elsewhere on the production server to allow access to these files.
Can anyone help? Thanks in advance!
Peter
In iis you would need to create a virtual dir that points to the images folder. Although putting images outside the wwwroot is pointless as they must be web accessible in order for them to display on a web page. The only reason to do this would be.if you were protecting copyright images with passwords and not linking to them directly.
If your on IIS, you may want to look at this for your web.config
http://www.iis.net/configreference/system.applicationhost/sites/site/application/virtualdirectory
here is a sample:
<site name="Contoso" id="2" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="C:\Contoso\Content" />
</application>
<application path="/CRM">
<virtualDirectory path="/" physicalPath="C:\Contoso\Content\CRM" />
<virtualDirectory path="/Images" physicalPath="E:\Images" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:80:www.contoso.com" />
</bindings>
</site>
This is wrong C:\extSite\stdImages\
You have to use slashes not backslashes for CF
This is correct and works C:/extSite/stdImages/

Update IIS binding in configuration file, not GUI

Can I update IIS binding in configuration file? I have six servers, needing to sync bindings among them.
Do you have any idea to facilitate my task? Thanks.
You sure can use Bindings/Binding element in the web server's ApplicationHost.config (not Web.Config) to setup multiple bindings directly similar to as below however be sure to keep the setting site specific so bindings reflect correct setting to specific site:
<site name="Contoso" id="2">
<application path="/" applicationPool="Contoso">
<virtualDirectory path="/" physicalPath="C:\inetpub\wwwroot" />
</application>
<bindings>
<binding protocol="http" bindingInformation="192.168.0.1:443:www.contoso.com" />
<binding protocol="https" bindingInformation="*:443:" />
</bindings>
</site>
More info:
http://www.iis.net/ConfigReference/system.applicationHost/sites/site/bindings/binding

Resources