I have a multi-site web role set up in Azure. In my service definition file I have the following:
<Sites>
<Site name="Web" physicalDirectory="..\ABC.WebUx">
<Bindings>
<Binding name="Abc" endpointName="Endpoint1" hostHeader="www.abc.com" />
</Bindings>
</Site>
<Site name="DEF" physicalDirectory="..\DEF.WebUx">
<Bindings>
<Binding name="Def" endpointName="Endpoint1" hostHeader="www.def.com" />
</Bindings>
</Site>
<Site name="Ghi" physicalDirectory="..\GHI.WebUx">
<Bindings>
<Binding name="Ghi" endpointName="Endpoint1" hostHeader="www.ghi.com" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>
The hostheader works good when I try www.def.com and www.ghi.com however when entering www.abc.com it seems to ignore the physical directory and instead gives me a message like this:
Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
The request for 'Home' has found the following matching controllers:
ABC.WebUx.Controllers.HomeController
DEF.WebUx.Controllers.HomeController
GHI.WebUx.Controllers.HomeController
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
Does anyone know why it seems to ignore the physical directory for the default "Web" which btw is the site that I have linked to my cloud service.
Your help would be much appreciated.
Nancy
If you're working with multiple websites I would recommend watching this Cloud Cover episode. During the episode they discuss that any site that has the name "Web" is treated as a special case by Azure and so properties like the physical directory are ignored. So to fix your specific problem change the name of your first site from "Web" to "ABC".
The default "web" site will always point to the project folder for the web role in your solution. You cannot overwrite it using the physicalDirectory attribute.
Related
I am getting following error when executing cspack command
"Error CloudServices051 : The XML specification is not valid: The element 'WebRole' in namespace 'http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition' has incomplete content. List of possible elements expected: 'Sites' in namespace 'http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition'."
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="CloudService1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebRole1" enableNativeCodeExecution="false">
<InputEndpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80"/>
</InputEndpoints>
<ConfigurationSettings/>
</WebRole>
</ServiceDefinition>
My guess from you example is that you're working with the book Programming Windows Azure, by Sririam Krishnan.
This was published in May 2010. Either the book presented a broken example, or some breaking change has since been introduced to the Azure framework since then.
Below is the ServiceDefinition.csdef file from page 51, modified to work with the Azure SDK v2.8:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="CloudService1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" >
<WebRole name="WebRole1" enableNativeCodeExecution="false">
<InputEndpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
</InputEndpoints>
<ConfigurationSettings />
<!-- This sites node was not included in the example -->
<Sites>
<Site name="TokenSite" physicalDirectory="htmlwebsite">
<Bindings>
<Binding name="BindingOne" endpointName="HttpIn" />
</Bindings>
</Site>
</Sites>
</WebRole>
</ServiceDefinition>
The addition was the Sites node, containing one site. The physicalDirectory attribute had to point to the folder that contains the html file. Until I added the Sites node, the cspack utility failed.
Interestingly, if you read about the Sites element in the Azure Online Documentation, (last updated April 15th, 2015), it explicitly says:
If you do not specify a Sites element, your web role is hosted as legacy web role and you can only have one website hosted in your web role. ... This element is optional and a role can have only one sites block. (my italics)
I'm trying to deploy a test instance of our Azure-based webservice to the new D-series Azure vm's. We make extensive use of temp files and are hoping we'll see some good performance improvements. Unfortunately we don't seem to be able to package or build using the new vmsizes. Our current csdef looks like this:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WebAPI.Azure" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2013-10.2.2">
<WebRole name="WebAPI" vmsize="Large">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="NonSSL Endpoint" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="NonSSL Endpoint" protocol="http" port="80" />
<InternalEndpoint name="InternalHttpIn" protocol="http" />
</Endpoints>
</WebRole>
</ServiceDefinition>
If I switch the vmsize from "Large" to "Standard_D3" and try to build or package for publishing, I get this error:
Error 2 The XML specification is not valid: The 'vmsize' attribute is invalid - The value 'Standard_D3' is invalid according to its datatype 'http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition:RoleSize' - The Enumeration constraint failed. C:\Users\ablack\Desktop\WebAPI.Azure\ServiceDefinition.csdef 3 34 WebAPI.Azure
How do I get this schema updated? Or is there a way to override XML validation during the build & package process?
Apparently the 2.4 SDK removes the vmsize constraint entirely (it accepts any values, including made-up values like "Supersize"), so we will have to upgrade to that to try any new size options. This will complicate benchmarking (we'll need to get fresh baselines with the updated SDK first), but c'est la vie.
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!
http://msdn.microsoft.com/en-us/library/windowsazure/gg433110.aspx
<Site name="ClientService" physicalDirectory="..\qwer.ClientService">
<Bindings>
<Binding name="ClientService" endpointName="EndpointClientService" hostHeader="ClientService.tsasdc.com" />
</Bindings>
</Site>
error
Error 1 The same local port '80' is assigned to input endpoints EndpointImageService and Endpoint1 in role qwer.Web. C:\Users\Administrator\Desktop\prohect\src\qwer.Azure\ServiceDefinition.csdef 1 1 qwer.Azure
You must use one and the same EndPoint for all the sites you need. That is the need for defining the "hostHeader" in each Binding. For example, if you want a port 80 HTTP endpoint - you may have only one endpoint per Hosted Service. And you just map all your sites to the same endpoint.
Endpoint1 is predefined HTTP input endpoint on port 80 when you have Web Role. You can either rename it to something more meaningful, or just use it for your second site, and never create second input endpoint on HTTP protocol and port 80.
You can have a few web sites, but they each have to point to their own unique port. If you had multiple on the same port, it wouldn't know which one to send the request to.
both of your sites should have the same endpoint name.
you got site with endpoint name Endpoint1;
the second site ( with the physicalDirectory attr) should go to the same endpoint with a hostHeader you already put.
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
</Bindings>
</Site>
<Site name="Web2" physicalDirectory="XXX">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" hostHeader="YOUR HOST HEADER" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>`
I have deployed an ASP.NET web application to Azure running in a web role. It is configured with a DNS name like 'myapp.cloudapp.net' and SSL (the certificate is self-signed, meaning we get a certificate warning but otherwise this is all set up and works fine)
I want to automagically route requests the come on http to https. So, I added an http endpoint and set up a rewrite rule as per the instructions here (second method):
http://blog.smarx.com/posts/redirecting-to-https-in-windows-azure-two-methods
It doesn't work properly.
Testing directly on the Azure machine (via remote desktop):
Access https://myapp.cloudapp.net - works
Access http://myapp.cloudapp.net - "Internet explorer cannot display the webpage"
So I go to IIS and 'browse' my site: this takes me there via the IP address:
Access https://[ipaddress] - works
Access http://[ipaddress] - works! Sends me to https://[ipaddress]
So what am I missing, that this works via IP address but not by host name?
I would like to hit http://myapp.cloudapp.net and be redirected to https://myapp.cloudapp.net.
For the record, here is the relevant parts of my configuration:
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="MyApp" />
<Binding name="Endpoint1" endpointName="MyAppHttp" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="MyApp" protocol="https" port="443" certificate="MYCERT" />
<InputEndpoint name="MyAppHttp" protocol="http" port="80" />
</Endpoints>
<Certificates>
<Certificate name="MYCERT" storeLocation="LocalMachine" storeName="My" />
</Certificates>
Can anyone help explain what I might be doing wrong?
Thanks in advance
Not a lot to go on, but one thing that jumps out at me is the 'name' of your bindings. Make them different.