Tag Cloud
#noestimates (1) AJAX (2) ASP.NET MVC (26) ASP.NET Web API (1) Agile (9) Android (1) AngularJS (1) Autofac (5) Azure AD (3) Azure Resource Manager (1) AzureWebFarm (1) BDD (1) C# (51) CSS (1) ColdFusion (3) Cordova (1) Domain Driven Design (1) Entity Framework (1) FluentMVCTesting (1) Git (1) HTML (7) IDE (1) IIS (1) JavaScript (11) MSBuild (3) MSDeploy (6) NHibernate (6) NSubstitute (6) NuGet (11) OctopusDeploy (1) OpenText (1) Pair Programming (3) PhoneGap (2) QUnit (1) REST (1) ReSharper (4) RedDot (1) Ruby On Rails (RoR) (1) Software Engineering (13) TDD (15) TeamCity (7) TestStack (1) Visual Studio (5) Windows Azure (28) Wordpress (1) accelerator for web roles (2) acceptance criteria (1) authentication (2) blogging (1) consistency (4) continuous delivery (15) continuous integration (1) convention (6) cryptography (1) dev ops (17) filter provider (1) forms (6) hypermedia (1) iPad (1) identity (1) jQuery (7) language (1) lean (4) maintainability (1) metro style (2) mocking (8) model binding (1) modern ui (1) powershell (10) razor (3) semantics (3) sql (7) t&l (1) tech evangelism (19) testing (37) text editor (1) unobtrusive coding (9) validation (4) windows 8 (2) winrt (1) xaml (2)
Latest tweets by @robdmoorePosts - Page 16 of 22
Type-safe ViewBag use to pass generic view data to views / layouts
It seems there are a number of different approaches to passing data (that doesn’t make sense to put into the view model) to the view in ASP.NET MVC:
- http://stackoverflow.com/questions/78548/passing-data-to-master-page-in-asp-net-mvc
- http://stackoverflow.com/questions/6979629/alternative-to-viewbag-title-in-asp-net-mvc-3
- http://www.heartysoft.com/ViewBag-can-be-goode280a6honestly
My preferred approach
I think that using the ViewBag is great because syntactically it’s much terser than ViewData and once you have used it once on a page then you will get intellisense for it. Personally, I think that having a base view model class that you use across your whole site is probably asking for trouble and from a separation of concerns point of view is just plain bad practice.
That’s one of the reasons why the ViewBag or even ViewData is good - they are completely separate from the view model so for data that it semantically doesn’t make sense to in include the view model of the page it’s the best place to put it.
I will say this with a disclaimer though, I think it’s important to minimise the amount of data you do pass in this way because otherwise you will get crazy spaghetti code that is hard to test and maintain. I will usually restrict using these data structures to data that I want to pass through to the base site layout. Things like the object representing the currently logged in user (e.g. their name, email address etc.) or a list of JavaScript and / or CSS files that should be included for the current page. Wherever it’s possible and it makes sense to put data in the strongly typed view model I think this is the best approach.
What I don’t like about ViewBag
The topic of using dynamics in C# is a pretty heated topic and there is much debate on either side. I think as always a pragmatic approach is required, but where possible I do prefer to avoid dynamics because they aren’t compile safe. While some people love to argue that it doesn’t matter and that the compiler is the first in a series of checks that you will perform, coming from an embedded background (I studied Embedded Software Engineering at University), I can’t help but appreciate and respect type-safety (let alone intellisense, which makes code easier to read/write and thus maintain!) :)
Type-safe / intellisensed ViewBag access in views
In the interest of providing some consistency and assurance about using the ViewBag there is a technique I have been using for a while now to expose the getting (and setting if from views) of ViewBag properties by wrapping them in properties within the base page class.
In order to do this I simply extend the default base page class (WebViewPage<T>
) and add relevant properties. I will usually locate this class directly in the Views folder (it semantically makes sense to me). An example implementation might be:
namespace MyWebApp.Views
{
public abstract class BasePage<T> : WebViewPage<T>
{
public User CurrentUser { get { return (User) ViewBag.CurrentUser; } }
public string Title { get { return (string) ViewBag.Title; } set { ViewBag.Title = value; } }
public bool HideMenu { get { return (bool)(ViewBag.HideMenu ?? false); } set { ViewBag.HideMenu = value; } }
}
public abstract class BasePage : BasePage<dynamic> {}
}```
There are a few things to note here:
- The classes are abstract because they shouldn't be instantiated directly, but rather extended by the Razor engine when compiling each page - [more info](http://stackoverflow.com/questions/4163545/why-is-webviewpage-in-mvc3-abstract).
- I provide a non-generic class (BasePage) as well as the generic one (the generic type being the view model type) because otherwise the intellisense in the web.config (see below) file complains. I used to think this was for views that don't specify an @model type, but I just tried it and it worked without that class there.
- The properties that I want the views to set values for have setters - this ensures that views can only set the correct type of value into the given ViewBag property (making the assumption you use this in preference to direct ViewBag calls in views from now on!).
- There is a property that I expect to be injected into ViewBag by the controller or a filter so it only has a getter.
Once you have done this then setting / accessing the properties in the view becomes dead simple (and terser than using ViewBag!) as well as giving you wonderful intellisense:
```csharp
@{
Title = "My Page Title";
HideMenu = true;
}
<h1>My page</h1>
@if (CurrentUser == null)
{
<p>You aren't logged in</p>
}
else
{
<p>@CurrentUser.FirstName is your first name!</p>
}
There is one thing I’ve missed out, which is to get Razor to compile using this new base page and to get intellisense working you have to either:
- Use @inherits on every page - ugh; or
- Change the pageBaseType attribute in the pages element in the system.web.webPages.razor element in the web.config file in the Views directory to be the class you’ve created e.g.
(also, feel free to add any common namespaces that you use across your views to the namespaces element and that way you don't have to put in an @using statement for those namespaces in the views any more!)
Injecting information from the controller
One thing that I’ve noticed some people do with this technique is to return something from DependencyResolver in the properties or use property injection from their dependency injection framework. While I’m all for unobtrusively setting these properties where possible (e.g. say you have an enumeration with the current environment (test / prod etc.) so you can do simple feature toggles in your views), it strikes me that it’s probably not a good idea because it will encourage business logic to be called from within views (e.g. if you decided it would be easier to inject a database repository in one of the properties). I think it’s way more testable and consistent to have any properties that are set outside of the views to be set from either:
- The controller - for instance you might have a base controller (if you rely on the base controller being used across the site it might be worth adding tests to check that this is the case [see Other Applications at the bottom of that post])
- A global filter
Grouping ViewBag access together
One of the really nice side-effects of this approach (of abstracting ViewBag access to the base page) is that your ViewBag access is now grouped together in the same file so it’s easy to see at a glance how you are using it. This means you are less likely to let the ViewBag use explode out of control!
Other applications of a custom base page
The custom base page is a really nice abstraction and opens up a lot of interesting possibilities. One example that I have used it for is to include page-specific CSS and JavaScript files into the <head> of the document by specifying them within each page using functions on the base page. These functions set the JavaScript and CSS files into the ViewBag and then the layout simply uses these when outputting the HTML in <head>. Razor seems to execute the view before the layout hence why this works!
protected void AddScript(string script)
{
var localPath = new Regex(@"^w");
if (localPath.Match(script).Success)
{
script = "~/Scripts/" + script;
if (!script.EndsWith(".js"))
{
script += ".js";
}
}
if (ViewBag.Scripts == null)
{
ViewBag.Scripts = new List<string>();
}
ViewBag.Scripts.Add(script);
}
public void AddStylesheet(string cssFile)
{
var localPath = new Regex(@"^w");
if (localPath.Match(cssFile).Success)
{
cssFile = "~/Content/Css/" + cssFile;
if (!cssFile.EndsWith(".css"))
{
cssFile += ".css";
}
}
if (ViewBag.Stylesheets == null)
{
ViewBag.Stylesheets = new List<string>();
}
ViewBag.Stylesheets.Add(cssFile);
}
A note about the current user property in the base page
I illustrated some code above that exposed the current user to the views. To populate this value you probably need a database call and if you are in the situation where you don’t need to use the CurrentUser property on every page it makes sense to lazy load the value so you don’t take an unnecessary hit to the database on every request. One approach I’ve used in the past to combat this is to expose CurrentUser in the ViewBag as a functor rather than a straight object value, e.g.:
public abstract class BaseController : Controller
{
private readonly IUserRepository _userRepository;
private User _currentUser;
public User CurrentUser
{
get { return _currentUser ?? (_currentUser = GetCurrentUser()); }
}
protected BaseController(IUserRepository userRepository)
{
_userRepository = userRepository;
Func<User> userGetter = () => CurrentUser;
ViewBag.CurrentUser = userGetter;
}
private User GetCurrentUser()
{
return ControllerContext.HttpContext.User.Identity.IsAuthenticated
? _userRepository.Get(HttpContext.User.Identity.Name)
: null;
}
}
...
public abstract class BasePage<T> : WebViewPage<T>
{
protected User CurrentUser
{
get
{
return ViewBag.CurrentUser != null ? ViewBag.CurrentUser() : null;
}
}
}
My take on documentation
I usually like to keep documentation for a project within OneNote due to the fact it’s really simple and easy to use (especially for dragging in attachments and images!), has first class integration with the Office suite and can be easily synced between team members by hosting the OneNote file in SharePoint or Windows Live. Second to that, I like to store relevant documentation alongside the code in source control so it is versioned and it encourages you to keep it up to date because it is “in your face”; this would normally consist of text-based documentation such as Markdown files. Wikis are also a reasonable option.
One of the things I think is often misunderstood about Agile is a perception that if you are doing Agile then you don’t need documentation. My take on it is that you should at any point in time focus on activities that deliver the maximum value. That means that if you are spending time writing superfluous documentation that won’t provide any value then it’s a waste of time. That doesn’t mean that all documentation doesn’t provide value though; on the contrary, documentation is really important. If there is insufficient documentation for an application then how can a support team be expected to support that application? Similarly, a lack of documentation is a problem if someone is completely new to an application and don’t know where to start looking or know any of the important background information behind it. Documentation plays an important role in the maintainability of any solution.
I see documentation of a system as a combination of:
- The code itself - thus making it important that code is written in such a way that it is as readable as possible and the intent of the code clear, it also means sections of the code that are hard to read / complex / non-standard should be annotated with comments and in the interest of keeping the code as terse and quick to read as possible leaving comments out of the self-explanatory parts of the code. As an extension of this, I only see it as necessary to add xml-doc comments to interfaces that are used across an application and any public classes in a shared library.
- The tests - the tests should be an expression of your intent on the design of the system and thus should be able to form a part of the documentation of a system.
- Other appropriate documentation - by appropriate I mean that the format the documentation is in is the most optimal format for the “thing” being documented. For instance, the documentation to specify a report that needs to be created should probably be a sample Excel file of the report (which is going to be a lot easier, more expressive and more understandable than a chunk of text to describe the report).
I also think it’s important to tailor documentation to the audience; the documentation doesn’t provide value unless it’s accessible and understandable to the people that need to read it.
AutofacContrib.NSubstitute v3 release
I’d like to announce a new release for the AutofacContrib.NSubstitute library. The library was in need of a bit of love because it forced you to use a really old NSubstitute version.
I’ve made the following changes:
- Deprecated the AutoMock class in favour of AutoSubstitute (in keeping with the theme of the NSubstitute library).
- Added a new constructor that allows you to make modifications to the ContainerBuilder before the IContainer is built.
- Dependency on the latest version of NSubstitute and removed the hard restriction on the NSubstitute and Autofac version numbers so the package is compatible with the latest versions of those libraries.
- Moved the source to Github
- Added some documentation and an example class showing some usage examples
Enjoy!
Windows Azure Web Sites (App Service: Web Apps) vs Web Roles
Welcome! This is a post that covers in great detail the differences between Windows Azure Web Sites (App Service: Web Apps as they are now called - this article will just refer to them by their original name) and Windows Azure Web Roles (azurewebsites.net vs cloudapp.net). It was first written a couple of days after Web Sites was first released, but I have been keeping it up to date as changes to Web Sites are announced. There is a change log of updates at the bottom of the post and I have struck out content that becomes out of date over time. There is also a good official Microsoft post that gives a similar comparison, but not quite as comprehensive that you can also refer to.
Shameless Plug: If you are interested in using the power of Azure Web Roles with the nice deployment experience of Azure Web Sites then check out the AzureWebFarm and AzureWebFarm.OctopusDeploy libraries I work on.
Diagrammatic Overview
The Windows Azure Training Kit has a slide with a really nice overview of the three options for deploying web applications in Windows Azure (note: Virtual Machines are outside the scope of this post):
Options for deploying websites in Azure and comparison to on-premise hosting.
tl;dr
Azure Web Sites has the following advantages:
- Out of the box support for ASP.NET, python, PHP, node.js and classic ASP
- Out of the box support for near-instant Git, VSO, FTP, Web Deploy and Dropbox deployments
- Out of the box support for configuring a VSO build that can compile code and run tests as part of the deployment
- Instant roll-backs (when using Git or VSO deployments)
- Free, out-of-the-box valid HTTPS when using default azurewebsites.net domain
- Out-of-the-box manual and automated backup and restore
- Much faster site provisioning and scaling (often takes seconds)
- Simpler Visual Studio solution (no need for extra Cloud project)
- One-click install of common open-source blog and CMS platforms
- Friendlier, comprehensive in-built (read: one-click to activate) monitoring and diagnostics
- Automatic configuration modification and config transforms on deploy
- Multiple websites (deployed separately) on a single farm out of the box
- Memory dumps via a REST API
- Out-of-the-box support for remote debugging from Visual Studio
- Ability to have staging environment with custom domain name and ability to change configuration settings at the same time
- Always On Support to keep your application pool warmed up and (optionally) auto-heal any problems in your app pool
- Multiple programming language support for periodic and continuous background jobs
- Ability to view processes running the machine and their CPU and memory use from the Azure Portal and remotely kill rogue processes
- Ability to add pre-packaged extensibility via Site Extensions
- Ability to connect to on-premise resources securely without needing VPN via Hybrid connections
- In-built A/B testing / canary deployment ability using Testing in Production (TiP) / Traffic Routing feature
Azure Web Roles has the following advantages:
- Use non-standard HTTP and/or TCP ports
- Remote desktop into the VMs
- Faster Windows Azure Virtual Network connection
- Run arbitrary startup scripts with or without elevated privileges
- Use Azure Drive to mount NTFS volumes from blob storage
- More control over what diagnostic information you would like to collect
- Full control to configure IIS
- Perform complex autoscaling
- Scale to hundreds of VM instances (max in Web Sites is currently 10)
- Use Extra Small (low cost) and A4 (Extra Large) / A5 / A6 / A7 / A8 / A9 (intense workloads), D-series and G-series VM sizes
- Install SSL for unlimited custom domain names for free
- Resolve arbitrary domain names to your site without specifying them in the portal
- Configure affinity groups and make use of upgrade and fault domains
- Use the CDN against your web site content
- In-role cache nodes
- 99.95% SLA as opposed to a 99.9% SLA
- You get more than 50GB of disk space
- Ability to use GDI+, Report Viewer and DNS lookups in your code
- Ability to make calls to localhost
- Access to performance counters
Sometimes Virtual Machines are a valid choice - check out my whitepaper on deploying web applications in Azure for more information.
Conclusion
If you need enormous scale, a non-standard/complex configuration (e.g. full IIS customisation, non-standard ports, complex diagnostics or start up scripts / custom software installs), more than 50GB of disk space or RDP then you need Web Roles.
In most other scenarios Web Sites is the best choice since it’s the simplest option and is fully-managed. The Web Sites platform is being constantly innovated on with new features surfacing almost every month – Microsoft are investing a lot of resources into making sure it’s a state of the art platform. If your application grows in complexity over time and needs to migrate from Web Sites to Web Roles or Web Roles to Virtual Machines this is a relatively easy process so you should be able to start with the simplest option initially (Web Sites) with confidence you can change later if required.
Web Sites
Long-story short: Convention-over-configuration IIS-as-a-service to get you up and running quickly in Azure with a minimum of fuss (kind of like App Harbor). Also, it allows you to use a certain amount of Azure resources for free (10 websites on shared instances with limited bandwidth), which is a welcome addition and will be great for proof of concepts or just playing around with stuff!
The advantages that Web Sites seems to have over Web Roles are:
- Out of the box support for Git (including hosted within Azure, CodePlex, Github and Bitbucket), VSO, FTP and Web Deploy and Dropbox deployments, which makes automated deployments and continuous delivery dead easy (not that it’s terribly difficult using PowerShell for Web Roles), and importantly, quick.
- Annoyingly (unless I’ve missed something), the git publishing doesn’t use private keys so you have to keep typing in the password, although from watching David Ebbo’s Youtube video on publishing from Git there must be some way to make it remember the password (I wouldn’t know as I always use private keys). [See update at end of post for instructions]
- It would be cool if some of these features were added to Web Roles and Worker Roles
; I’m not sure if this tweet from David Ebbo is any indication that might happen! It seems thatMicrosoft have open sourced their Git-IIS deployment library, Kudu, which is cool :)- I tried to deploy a solution that had multiple web projects, but no matter what I did it kept deploying the first web project that I had deployed. I’m not sure what conventions it uses, but if you need to configure which project is deployed then I imagine you can consult the relevant Kudu documentation (edit: looks like there are some ways to address it).
- If you use the Git publishing model
(and I assume the TFS publishing model)then you don’t have to commit your NuGet package binaries as they will automatically get resolved when you push (you do have to turn on Package Restore on the solution in Visual Studio for it to do it though- edit: package restore is being deprecated). This is great because it makes your deployment much faster. It does mean that if you use packages that aren’t in the official NuGet repository (e.g. in a private repository, or using a package service) then you will need to include those ones or update the nuget config- I haven’t tried seeing what happens when you do that though yet, so try with caution.
- Gives you the ability to roll-back to previous deployments instantly via the management portal if you are using Git
(and I assume TFS)deployments.
- You can deploy almost instantly out of the box (with the above mentioned deployment methods), rather than in 8-12 minutes or having to set up something like
Accelerator for Web RolesAzure Web Farm or AzureWebFarm.OctopusDeploy. - You can provision a new Web Site much faster than a Web Role (seconds rather than 8+ minutes); I’m guessing Microsoft will always have spare capacity spun up and ready at any point in time - their capacity management software must be fascinating!
- For .NET web apps: You don’t have to set up a separate project in your Visual Studio solution to deploy to Azure - you can simply deploy a normal web app solution as-is.
- This also means you don’t have to maintain two sets of configurations and set up a storage account for diagnostics so you can be up and running much quicker.
- Out of the box support for installing ready-to-go, open source web applications (from a list of common ones; mainly CMS’s and blogs).
Built-in monitoring from the management portal(Web Roles has CPU and (optionally) memory as well now, but this also includes HTTP errors, requests and data)Web Sites has out of the box support for per-minute diagnostics now, which you can get the data for with Web Roles, but it’s all in-built into the portal for Web Sites and easier to use / consume:
- Extra diagnostics options at the click of a button:
- Ability to inject configuration variables to your web.config file rather than having to package the final version with the deployment.
- This means you don’t have to use encrypted web.config files if you want to keep production configuration information in source control so you can do automated deployments, but still prevent developers from accessing the production environment.
- It does mean you potentially need to be more careful about who you give access to the management portal for your instances because the connection strings will
appear in plain textbe accessible to them.
- If you have a web.release.config file then the XDT transformations in this file will automatically be applied before deploying your site.
- You can add multiple host names that your site responds to (if it’s using
reserved instancesstandard or shared tier, but not forsharedfree tier).- It appears you have to do this if you want to point a CName record at the site - given there are multiple sites being hosted on the same IIS instances this makes sense.
- Given Web Roles allow you to point as many domain names as you want at it and it will resolve for all of them (assuming you are trying to resolve the main web site that is deployed in the Azure package rather than using a solution like
Accelerator for Web RolesAzure Web Farm, which does require you to specify the host name) this isn’t really an advantage that Web Sites has over Web Roles. - What it does mean though is that you can host multiple sites on a single set of reserved serversout of the box (which is why Web Sites deprecated Accelerator for Web Roles in combination with near-instant deployments).
- There is an implication if you are using
sharedfree tier rather thanreservedstandard or shared tiers that you can’t point custom domain names to your web site and thus have to use the azurewebsites.net domain name (which is probably fine if you are doing a prototype or proof of concept). It seems that for a given subscription in a given region you can have either free/shared or reserved Web Sites and thus any web sites that you add for a given subscription / region that has reserved Web Sites will be shared on your reserved servers.I can’t confirm this explicitly, but it’s the only thing that makes sense to me after seeing the management portal and reading between the lines in the documentation.I would suggest that it will be important to keep this in mind if you want to segregate the servers that certain combinations of web sites that you deploy. You might want to do this due to their load profiles conflicting with each other. This is important unless Microsoft provides an easy way in the future to segregate your reserved instances within a single subscription or provide an easy way to migrate a site to a different subscription or region (unless I am missing something!).
- You can use MySQL (edit: You can use this with Web Roles easily too now by adding a MySQL database using Add-ons).
- You only need one instance to get the SLA rather than 2 instances in Web Roles
- It supports multiple programming languages out of the box
- It takes seconds rather than minutes to scale up and out as well as changing tier.
- You can host your “naked” domain name (i.e. without www.) in a supported way rather than having to resort to external services, clever programmatic solutions or being careful not to nuke your deployment.
- You can get memory dumps via a REST API via Kudu
- You can perform remote debugging from Visual Studio
- You can keep your application pool constantly warmed up with Always On Support
- As part of the Always On support you can define triggers that result in your app pool recycling automatically to auto-heal any problems in your website
- You can run periodic or continuous background jobs in multiple languages out of the box and you can deploy them as part of deploying your web application
- You can use a staging environment and immediately switch the files to production, while changing connection strings etc. plus you can assign a custom DNS name to your staging environment rather than the random
.cloudapp.net domain name for the Web Role staging slot (see the below comment from joshka though) - You get free, valid HTTPS out-of-the-box with the azurewebsites.net domain
- You get out-of-the-box support for manual and automated backup and restore
- Ability to view processes running the machine and their CPU and memory use from the Azure Portal and remotely kill rogue processes
- Ability to add pre-packaged extensibility to your web site at the click of a button via Site Extensions
- You can connect to on-premise resources securely without needing a VPN using Hybrid Connections
- There is an in-built function that allows you to perform A/B testing and canary deployments called Testing in Production (TiP) / Traffic Routing
Web Roles
With all that in mind, this is what I see as the advantages of / situations you would use Web Roles (a lot of those also apply to Virtual Machines, but that is outside the scope of this post):
- If you need to create an application that has non standard HTTP ports open (or frankly ports open for non-HTTP traffic) you can’t use Web Sites.
- You can’t RDP into the server for debugging or other purposes when using Web Sites.
If you want surety about network / virtual machine isolation of your application for security reasons you may not want to use (at the very least free/shared) Web Sites. This is a bit of conjecture though because without knowing the internals of how Web Sites is implemented it’s hard to say what kind of isolation it provides.(edit: VM isolation will be the same for standard tier, see next point about network isolation)You can use Windows Azure Virtual Networks to get network isolation of your Web Roles, but this can’t be used with Web Sites(edit: you can connect an Azure Web Site to a Virtual Network using a Point-To-Site VPN connection, which is limited to 100 Mbps, whereas Web Roles can be directly connected to the network)If you want to deploy a worker role to perform background processing alongside your web site via a worker role then you can do it using the same instance with a Web Role (thus costing less money; also, Azure Web Farm has the ability to support execution of console applications packaged with your web application providing the same kind of benefit).(edit: Web Sites now supports Web Jobs so this point is no longer relevant)- You can run elevated start up scripts with a Web Role that then allow you to install any software you want or configure it in any way you desire.
- You can mount a NTFS filesystem stored in blob storage using Azure Drive
- You have full control over what diagnostic information is collected from a Web Role, which you may want to use for auto scaling, or customised monitoring solutions.
- You have full control over how IIS is configured in a Web Role; note: it’s worth noting that Microsoft are consistently opening up IIS configuration options from web.config.
Your Web Role endpoint resolves to a static IP address assuming you don’t nuke your deployment. edit: the fact you can have A Record support means this can be achieved with Web Sites too.edit: both Web Sites and Web Roles allow for A-record support, with Web Roles you can reserve a static IP address.-
You can automatically scale your web site using Web Roles.You can perform much more complex auto-scaling with Web Roles - the slider-based auto-scaling in the portal is much more comprehensive and allows CPU and Azure Storage Queue based scalingand time schedules(edit: Web Sites now has the ability to scale using time schedules in the portal) and if you want even more complex auto-scaling you can use the Autoscaling Application Block (aka WASABi)
- You can scale out to a very large number of instances for extremely high load web sites (I know of a situation where at least 250 instances were used). Web Sites
(at least at the moment, and with the default configuration when you first get it - it’s potentially possible to increase this) seems to have a maximum of three instanceshas a maximum of 6 shared or 10reservedstandard instances. Furthermore, as per above screen shot and at least for the moment,Web Sites doesn’t have Extra Small (great for cost effective hosting of low load web sites - but the free and shared instances make up for this) or A4 (Extra Large) / A5 / A6 / A7 / A8 / A9 / D-series / G-series (if you need extreme vertical scale - but you probably only need this for intense Worker Role processing rather than for web sites [unless you are doing something very wrong/weird with your web application :P]).At the moment you can only have SSL connections to your custom domain name by using Web Roles since there is no ability to upload Security Certificates to your Web Site instances, but this will probably be added soon. There is SSL for the azurewebsites.net domain name that you get though.edit: SSL for custom domain names in Azure Web Sites has been released, but it comes at a cost, whereas you can install SSL to your Web Role for free.If you want securely managed Security Certificates for any other purpose than SSL e.g. config encryption, authentication, etc. then you will need to use Web Roles (for now at least).edit: you can now use Azure Web Sites for arbitrary certificates.Apparently, during the preview there is a limit of 1GB of space per subscription that can be used with Web Sites and you can have a maximum of 10 web sites. I found this in a Stack Overflow answer from a Microsoft employee working on Azure. Free and paid shared instances have a limit of 1GB of space with free instances having a limit of 10 websites and shared instances having a limit of 100 websites (reservedstandard instances have 10GB of space and a 500 website limit [I wonder if this is an IIS limit otherwise why would it be there since you have a complete VM(s) at your disposal?]). WithAccelerator for Web RolesAzure Web Farm and AzureWebFarm.OctopusDeploy there is no limit on the number of sites, and depending on your role size you can certainly have more than 1 GB of storage (apart from the fact you have have more than one hosted service, each with more than 1 GB of space).- If you want to have any domain name you want to resolve against your web site using a CName without having to specify those domain names explicitly in the management portal then you will need to use Web Roles (see the comments section below for explanation).
You have the option of using VIP swap as a deployment option - this allows you to fully test the deployment you are about to make and then switch between old and new very quickly (and more usefully, vice versa if something goes wrong)(edit: Web Sites now has a staging environment with similar (but more advanced) functionality)- While I think this is very useful in some circumstances, particularly if the act of deploying is accompanied by separate, long-running processes that could go wrong (e.g. complex database changes that are triggered before the vip swap) I think in general if you can simplify your deployment process such that it’s not required (and simply make it really quick and easy to rollback to the last version) then that’s better (Web Sites enables this due to it’s out-of-the-box deployment options)
- Affinity groups to allow you to ensure that Web Roles are close to storage accounts and potentially other roles within the datacentre (decreasing latency and increasing performance).
I suspect that Web Sites may well do this behind the scenes for the storage account you associate with the Web Site, but of course you can only do it with that storage account and not with multiple ones or other sites / roles- You can create linked resources, which may (I can’t verify or find any information to back this up) provide the same effect - you can do this for Azure SQL Databases and storage accounts:
- Explicit upgrade and fault domains
- Web Sites makes upgrade domains redundant given the deployment options (see note above about VIP swap) and I assume that fault domains are likely transparently implemented for you, but that could be wrong
- In-role cache nodes
- The cscfg file and ability to edit in the portal
- You can edit web.config variables and connection strings within the portal for Web Sites so this makes it somewhat redundant
- If you want to use Traffic Manager to distribute your application in multiple data centres across the globe then you can’t use Web Sites, however you can get a similar affect using an Azure Virtual Machine and IIS ARR as per http://stackoverflow.com/questions/13697863/is-it-possible-to-provision-the-same-domain-name-on-multiple-azure-websites
- If you want to use the Content Delivery Network against your web site rather than a static Storage Account then you need a Cloud Service and can’t use Web Sites.
Windows Azure Web Roles has an SLA (99.95%), but Web Sites has no SLA.Web Sites has a 99.9% SLA whereas Web Roles has a 99.95% SLA.- Web Roles can be easily deleted and redeployed from a package in blob storage so if you only need your site functioning for part of the day you could delete the deployment when it’s not needed and have a significant cost saving.
- Web Roles are charged by the minute - I can’t work out if Web Sites are the same or not though, but I assume so since the pricing page talks about converting the usage to Compute hour equivalents.
- Web Roles have 64-bit app pools by default - Web Sites are 32-bit by default and in fact you have to upgrade to standard mode to get a 64-bit app pool; it is possible to downgrade the Web Role app pool to 32-bit
- If you want to use GDI+ or report viewer then that is not currently supported in Web Sites (but does work on Web Roles) - it is in the long term plan to add support and you can keep track of progress via the MSDN forums
- If you want to use DNS lookups in code then that isn’t possible in Azure Web Sites (sorry - I can’t find a link for this one)
The regions that you can deploy Web Sites to are currently restricted while this feature is in preview, but there are probably plans to roll out wider (see point 3 in the link) (edit: it’s available in all regions except South East Asia - I can’t find any reason why it’s not available in that region).
- You can make calls to localhost on the role, which isn’t possible in Azure Web Sites since it doesn’t use a * binding in IIS - instead you have to use the domain name of the site, which will go out through the Azure load balancer
- You can access performance counters
While reading up on this post I found out something about Web Roles that I didn’t know - apparently you can deploy a Web Role package that contains multiple web sites (by specifying their host headers), but it does mean that you have to always deploy all the websites at the same time and keep them all in the same Visual Studio solution.
Updates
Update (10 June 2012)
David Ebbo send me a message via Twitter to let me know the solution he is using to remember his Git password. Also, I found a post that describes how to point to other NuGet feeds than the official one when using package restore.
Update (28 August 2012)
I read a truly excellent post yesterday about Virtual Networks and it made the point that you can’t join a Web Site to a Virtual Network, but of course you can join a VM or Web/Worker Role. Thus I added that as another limitation above.
Update (15 September 2012)
West US Azure data centres now support Web Sites.
Update (18 September 2012)
There were a few big announcements today about Azure Web Sites and I’ve updated this post with some minor corrections accordingly.
Update (9 October 2012)
Added some rather obvious differences I originally missed thanks to the comment below from Roland.
Update (1 January 2013)
Updated to reflect the fact that East Asia is now supported for Azure Web Sites (as per this announcement) and the fact you can now have up to 6 shared and 10 reserved instances rather than the original 3 (as per this announcement).
Update (27 April 2013)
Updated to add the fact that Traffic Manager isn’t supported for Web Sites.
Update (25 May 2013)
Updated to add a note about CDN support as pointed out by Teo below.
Update (17 July 2013)
Overhaul of the post to get it up to date with recent changes to Web Sites and Web Roles as well as a general tidy up and making it more friendly (e.g. added diagram, new intro and tl;dr section and moved around some of the points that were in the wrong section).
Update (8 September 2013)
Added information about GDI+/Report Viewer as pointed out by Travis below.
Update (26 January 2014)
Added information about Web Sites staging environment, Always On Support, DNS lookups, AzureWebFarm.OctopusDeploy and In-role cache and emphasised the 10GB limit for Azure Web Sites.
Update (29 January 2014)
Added note about the web.config options for configuring IIS that are increasingly being opened up for Azure Web Sites.
Update (8 February 2014)
Added notes about A8 and A9 VM sizes, 32-bit vs 64-bit app pools and auto healing.
Update (22 October 2014)
Updated post to reflect the following:
- Out-of-the-box HTTPS with Azure Web Sites
- Azure Web Sites Backup
- Azure Web Sites Processes
- D-series and G-series VMs for Azure Web Roles
- VPN connection to a Virtual Network for Azure Web Sites
- South East Asia available for Azure Web Sites and TFS support is now VSO support with a build as per Josh’s comment
- Can’t make localhost calls on Azure Web Sites
- Site Extensions for Azure Web Sites
- Clarified that you can reserve a static IP for Web Roles for A record support now
- Out-of-the-box Remote Debugging with Azure Web Sites
Update (31 October 2014)
Updated post to mention Hybrid Connections support in Azure Web Sites and the fact that you can use custom certificates in Azure Web Sites now.
Update (6 April 2015)
Added some notes about App Service: Web Apps and added information about the TiP feature.
Update (3 January 2016)
Added note about access to performance counters as pointed out by Matt below.
Windows Azure announcements
Microsoft made a HUGE set of announcements to do with Windows Azure the other night (well, day if you are in the US). With this release Microsoft are demonstrating how serious they are about Azure and cloud computing, which can only lead to more innovation and exciting developments! While nothing that Microsoft have announced is particularly unique (most of it is on offer from providers like AWS and App Harbor), it really tightens up the Microsoft offering (which as a PaaS offering was already impressive). If Microsoft continue to pump development into Azure at the rate they have done then the other providers better watch out!
For anyone that saw my tweets after I read the above linked post then you will know that I am EXTREMELY excited about this release. In particular, the things that really struck me were the new portal (the old one is slow, clunky and you have to have Silverlight so no tablet or phone support if you don’t have a Windows device), the monitoring dashboard (previously you had to roll your own) and the new Websites feature.
I have spent a lot of time in the last few months playing around with speeding up Azure deployments and I wasn’t terribly happy with the solutions available. For web roles I was using Windows Azure Accelerator for Web Roles in combination with web deploys from a CI server and for worker roles I was using a PowerShell command that did an in place upgrade. This lead to deployment times of around 30 seconds and 8 minutes respectively. I am happy with 30s (although the Accelerator has a few deployment problems that I have come across that make it less robust than I would like), but 8 minutes is way too long. I actually have an idea for getting fast deployments of worker roles using a similar technique to Accelerator that I have been cooking up with my team’s Senior Developer, Matt Davies, but I’ll leave that for another post.
As Matt and I expected, the new Azure announcements have left the Accelerator project in a deprecated state. I actually think there are still valid uses of it, but I’ll leave that for another post too.
So long story short, I’m really happy that Microsoft have done a lot of work on making deployments and multi-tenant website hosting on Azure a snap because it was one of the biggest frustrations of Azure. Certainly, it was this that lead to the creation of App Harbor. I’ve had a bit of a play with App Harbor over the last 6 months, and while there are certain aspects of it that are very cool, in particular if you aren’t using a CI server, I’m not a huge fan so the Azure announcement is even more welcome news.