Razor Pages Fixes to Tag Helpers Issues

Razor Pages Fixes to Tag Helpers Issues

Recently when adding Razor Pages to an existing ASP.net Core MVC web application I had issues with the Tag Helpers not working. No markup was being produced. Not only were the tag helpers (i.e. asp-for) not doing their job of but I also noticed that the markup was not being formatted in bold in Visual Studio as it should be.

At this point I checked for a _ViewImports.cshtml file which I found before checking some other things (see the list below), however I failed to notice that as this was an MVC application with Razor Views there is already a _ViewImports.cshtml file but in the wrong place for my Razor Pages. The _ViewImports.cshtml file must be in the root of the Pages folder where your Razor pages reside, and so you will need one in both the Pages folder for your Razor Pages and also in the Views folder for your MVC Razor Views.

The _ViewImports.cshtml file must contain:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Adding a new _ViewImports.cshtml file under the Pages folder resolved my problem, but in the meantime here are some additional things to try if you have other Tag Helper problems:

  • Update all dependency Packages
  • Add/re-add Microsoft.AspNetCore.MVC.TagHelpers package if its missing
  • Check your _ViewImports.cshtml file is in the Pages folder or a parent folder of your Razor Pages. You may need one in the Areas folder if you have one.
  • Check that the _ViewImports.cshtml file includes a reference to Microsoft.AspNetCore.Mvc.TagHelpers. If it does try removing it, rebuilding the solution and then re-adding it, and rebuilding again.
  • Check the namespace in the _ViewImports.cshtml file is correct.
  • Should all these fail, try turning on the developer exception page and see if that helps to narrow down the problem.
Advertisements

Cheap Azure Hosting via Static Web Sites

Cheap Azure Hosting via Static Web Sites

Something that is pretty cool and not that well known is that you can now host your static web site in the cloud with Microsoft Azure just from your Azure storage account. The functionality is currently in preview only but its functional enough to get up and running quickly if you have an Azure account.

Why host a static site?

Whilst it does depend on your requirements many sites are quite capable of being static sites with no server side processing. The classic example is a blog site whereby the site could just serve up static html, images and JavaScript straight from disk as the content changes fairly infrequently.

The growth in JavaScript libraries and the functionality of frameworks like React.js make static sites even more viable. Using the power of JavaScript its possible to create rich powerful web applications that don’t need server side processing. There has been an explosion of static site generators over recent years that will take text or markdown files and generate a complete static site for you. Two very popular generators of note are Gatsby (React.js based) and Jekyll (Ruby) but there are literally hundreds of others as can be seen by this online directory: staticgen.com.

Hosting a static site in Azure

Of course you could always host a static site in Azure if you hosted it in a full featured web site (via a hosted VM or azure web site) but the beauty of a hosting a static only site is that you can host it straight out of storage area and so you don’t need to pay for any compute power which makes it extremely cheap (and even free). You just pay standard Azure storage rates which include a generous data transfer limit (about 5GB a month).

If you think about it hosting a static web site is just a natural extension for a cloud offering like Azure as they already host files and binary content on public URLs in Azure Storage. This new functionality though makes it more explicit and enables web site like functionality such as custom error pages. It is also possible to add your custom domain name to the site and link up SSL (although unfortunately at the moment SSL requires use of an Azure CDN which adds to the cost.)

So how do you host your site, well follow the official instructions here.

Once you have a web page being served by the default Azure storage URL you can proceed to add your own custom domain name using these steps.

Now you should have a fully working site, but to keep costs even lower we can utilise caching of our static content to encourage the client browser to cache the files thus reducing our data transfer costs. Luckily it is easy to set cache control settings on our Azure Blob storage items. This blog post by Alexandre Brisebois covers doing it in code but if you are just testing, or have a site that doesn’t change much you can do it manually via the Azure Portal. To do so enter your Azure Portal, browse to your Storage Account and then using Storage Explorer find the files you want to set caching for and go to their properties. In the Properties dialog you can set the Cache-control value in the HTTP header to something like…

 "public, max-age=86400". 

There are other alternatives to Azure for hosting static files and some offerings are very cheap or free. Some of these are more advanced than the current Azure offering and provide additional features such as integrated SSL and contact forms. One such vendor is netlify.com but there are others.

In summary, if you want to host a site cheaply and you dont really need server side processing then consider hosting a static site, and if you’re already using Azure then its a simple step to give it a go.

.

Developer Roadmaps

Developer Roadmaps

Something that’s proving popular on Medium these days are “development roadmaps” that outline a roadmap approach to choosing techniques and technologies for certain technical domains (for example Web development or Dev Ops). Some of these are particularly powerful for putting the many bewildering technologies all on one page with logical grouping and a visual representation of how they interact. Modern web development has seen so much change over recent times that it is very easy to get lost and become overwhelmed and these roadmaps can help clear the fog (a little).

My favourite is the Web Developer Roadmap in 2019 maintained by Kamran Ahmed over on GitHub.

I have shared this with several people who have also found it useful regardless of their level of expertise. The front end roadmap is a great guide to what the community are currently settling on as the standard choices for tooling and techniques. I have checked back to the roadmap a few times over the last 6 months to verify my approach when starting on a new project and I find that visualising the options makes decision making easier.

There are also Backend and DevOps Roadmaps included which are equally as useful.

For some more useful roadmaps check out this medium post.

Cmder – A Better Windows Console

Cmder – A Better Windows Console
Whilst Linux treats console users as first rate citizens and provides many useful and powerful terminal emulators Windows has always lagged behind. This is evermore noticeable now that many developer and IT Ops workloads are done via the terminal. Modern web development and DevOps tooling requires at least some interaction with the terminal, and with the world moving to git for source control developers everywhere are having to embrace consoles.
Whilst Microsoft have traditionally neglected the Windows console they have started to add new features and improvements. For a background on the Windows Console and its architecture check out this blog series. Windows 10 has the best Windows console to date, but there are better out there from 3rd parties and I’ve really got into Cmder.
Cmder is a smart per-configured bundle of the ConEmu emulator software with some extras thrown in. To quote directly from their website:
 

Cmder is a software package created out of pure frustration over the absence of nice console emulators on Windows. It is based on amazing software, and spiced up with the Monokai color scheme and a custom prompt layout, looking sexy from the start.

It can be run portable on a USB Stick if you wish and it has full Git and Bash support. You can emulate the Windows Command Prompt or PowerShell, Bash, Windows SubSystem for Linux (WSL), even the VS Developer Command Prompt among others. All in a slick feature rich emulator.

cmder

It has hundreds of settings that can be tweaked to get everything just the way you like it and it also has the awesome Quake mode so it can slide down from the top of your display.
Cmder2
Support for Cmd, PowerShell, Bash and many more is included out the box, but if you are a Visual Studio user and want to emulate the Developer Command Prompt for VS2017 (reommended) then check out the simple instructions in this guide by Ricardo Serradas on Medium.
I’ve been using it for months and its been stable, performant and has also caught the eye of collegues due to those good looks which make it a pleasure to work in compared to the plain Windows console. Give it a try.

A Custom JSF Tag Lib For Toggling Render of Child Elements

A Custom JSF Tag Lib For Toggling Render of Child Elements

 

I’ve added a new sample project on GitHub that shows a custom Tag Library for JSF (Java Server Faces) that can be used to show/hide its children. There are several uses for this sort of custom component in your JSF web project but in this sample code I just read a property on the custom tag to determine whether to render all child elements or not. In a real application this logic could be swapped to implement application logic or perhaps call a Feature Toggle framework which decides whether to render elements within this tag or not.

Whilst the code is a complete same JSF project the main class is the CustomTag class.

This custom tag extends UIComponentBase to control the encodeChildren and getRendersChildren methods. In the getRendersChildren method we need to determine whether any child elements should be shown or not (again this can be any logic you find useful but for this example we are just reading a parameter on the XHTML). If its determined that we DO want to display children then we will follow normal processing and pass the call onto the base class’s getRendersChildren method. If its determined we DO NOT want to display child elements we instead return TRUE which tells the JSF framework that we want to render children ourselves using our custom encodeChildren method (which then ignores the request).

public class CustomTag extends UIComponentBase {

    @Override
    public String getFamily() {
         return "com.test.common.CustomTag";
    }

    @Override
    public void encodeChildren(FacesContext arg0) throws IOException {
         return;
    }

    @Override
    public boolean getRendersChildren() {
         boolean enabled = false;
         // Replace this logic with whatever you need to determine whether to display children or not
        String ruleName = (String) getAttributes().get("showChildren");
        enabled = (ruleName.equalsIgnoreCase("enabled"));

        if(enabled)
        {
             // we want the children rendered so we tell JSF that we wont be doing it in this custom tag.
             return super.getRendersChildren();
        }
        else {
             // we will tell JSF that we will render the children, but then we'll not.
             return true;
        }
    }
}

Next we define the new tag in the web.xml and custom.taglib.xml config files.

<!-- register custom tag -->
<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/custom.taglib.xml</param-value>
</context-param>

and

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
        "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
        "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://RichCustomTag.com</namespace>
    <tag>
        <tag-name>customTag</tag-name>
        <component>
            <component-type>com.test.common.CustomTag</component-type>
        </component>
    </tag>
</facelet-taglib>

We then use that new CustomTag within our XHTML page to wrap the elements that we want to toggle on/off depending on our logic.

Items below may or may not appear depending whether they are turned on or off:
<!-- to show children set showChildren to 'enabled' else 'disabled' -->
<rh:customTag showChildren="enabled">
   If you see this then child items are enabled
    <h:inputText value="#{helloBean.name2}"></h:inputText>
    end of dynamic content.
</rh:customTag>

That’s it.

Check out the code on GitHub via https://github.com/RichHewlett/JSFTag_ToggleChildRendering.

Speed up a slow JSF XHTML editing experience in Eclipse or IBM RAD/RSA.

Speed up a slow JSF XHTML editing experience in Eclipse or IBM RAD/RSA.

If you find yourself doing some JSF (Java Server Faces) development within either Eclipse, IBM’s RAD (Rapid Application Developer) or IBM RSA (Rational Software Architect) IDEs you may find that the JSF editor can run slowly with some lag. This seems particularly a problem on RAM starved machines and/or older versions of the Eclipse/RAD IDEs. The problem (which can be intermittent) is very frustrating and can result in whole seconds going by after typing before your changes appear in the editor. It seems that the JSF code validator is taking too long to re-validate the edited JSF code file. At one point this got so bad for our team many would revert to making JSF changes in a text editor and then copy/paste the final code into the IDE.

java_small

Thankfully there is a workaround and in order that I don’t forget if I hit this problem again I’m posting it here. The workaround (although sadly not a fix) is to use a different “editor” within the same IDE. If you right click the JSF file you want to edit and use the pop-up menu to choose to open it with the XML Editor instead of the XHTML Editor then you will find a much faster experience. Whilst this does remove some of the JSF/XHTML specific validations it provides support for tags etc and will perform faster.

Should you wish to always use the XML Editor to edit XHTML files you can make this global change via the preferences. Go to General > Editors > File Associations > File Types list > select XHTML extension > click Add > Add XML Editor. Then in the associated editors list select the XML Editor and click the ‘Default’ button – thus making XML Editor the default for all XHTML files. Of course once this is done you can still click on individual XHTML files and right click to open in the original XHTML editor should you want to temporarily switch back for an individual file.

Hopefully this will prevent you pulling your hair out in frustration when editing XHTML files.

Setting HTTP Headers in Java Server Faces (JSF)

Setting HTTP Headers in Java Server Faces (JSF)

In my last post  I discussed using HTTP headers to control browser caching of sensitive data. The post can be found here. The examples provided in that post were all ASP.Net and so I thought I’d cover how to explicitly set your HTTP Response headers when you are using the Java JSF framework.

Adding Headers via Code

You can set HTTP response headers directly in your code via the HTTPServletResponse object, as below:

import javax.servlet.http.HttpServletResponse;

ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
HttpServletResponse response =  (HttpServletResponse)context.getResponse();
response.setHeader("TestHeader", "hello");

This results in the addition of this header in the HTTP Response: TestHeader: hello.

Adding Headers in your XHTML Markup

Alternatively you can set it directly on each XHTML page via an event tag, as shown in the example below:

<f:event type="preRenderView" listener="#{facesContext.externalContext.response.setHeader('TestHeader', 'hello')}" />
  <h:form>
    <h:panelGrid columns="2">
      <h:outputText value="Name"></h:outputText>
      <h:inputText value="#{LoginBean.name}"></h:inputText>
      <h:outputText value="Password"></h:outputText>
      <h:inputSecret value="#{LoginBean.password}"></h:inputSecret>
    </h:panelGrid>
    <h:commandButton action="welcome" value="Submit" />
</h:form>

This again results in the addition of this header in the HTTP Response: TestHeader: hello.

Adding Headers via a custom Web Filter

In order to implement a solution across your whole web application and for the ability to set headers for different resource types (not just facelets), a web filter may be what you need. Filters intercept your requests and responses to dynamically transform them or use the information contained in them. A good guide to Filters is this official Oracle one – The Essentials of Filters, or check this one out – Servlet Filter to Set Response Headers .

Here is the source code for a simple filter that sets a custom header and can be used to explicitly set HTTP response headers as required:

package Filters; 
import java.io.IOException; 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletResponse;

public class HeaderFilter implements Filter 
{ 
    public void init(FilterConfig fc) throws ServletException {} 

    public void doFilter(ServletRequest req, ServletResponse res, 
            FilterChain fc) throws IOException, ServletException 
    { 
        HttpServletResponse response = (HttpServletResponse) res; 
        response.setHeader("TestHeader", "hello"); 
        fc.doFilter(req, res); 
    } 

    public void destroy() {} 
}

Once you’ve coded your filter you need to update your Web.xml file to tell the framework that you want to use this filter. Do this by adding a filter element containing the name and class details. You also need to set a filter-mapping element to map the filter with the request for resources. In the below example which configures the Filter above I have mapped “/*”  meaning all requests will go through the filter but you can configure this to only impact certain resources or file types.

<filter>
  <filter-name>MapThisCustomHeaderFilter</filter-name>
  <filter-class>Filters.HeaderFilter</filter-class>
  <init-param>
    <param-name>value</param-name>
    <param-value>test</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>MapThisCustomHeaderFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Once configured via the web.xml file the custom header sets this header on all respones: TestHeader : hello.

Preventing Browser Caching using HTTP Headers

Preventing Browser Caching using HTTP Headers

Many developers consider the use of HTTPS on a site enough security for a user’s data, however one area often overlooked is the caching of your sites pages by the users browser. By default (for performance) browsers will cache pages visited regardless of whether they are served via HTTP or HTTPS. This behaviour is not ideal for security as it allows an attacker to use the locally stored browser history and browser cache to read possibly sensitive data entered by a user during their web session. The attacker would need access to the users physical machine (either locally in the case of a shared device or remotely via remote access or malware). To avoid this scenario for your site you should consider informing the browser not to cache sensitive pages via the header values in your HTTP response. Unfortunately it’s not quite that easy as different browsers implement different policies and treat the various cache control values in HTTP headers differently.

Taking control of caching via the use of HTTP headers

To control how the browser (and any intermediate server) caches the pages within our web application we need to change the HTTP headers to explicitly prevent caching. The minimum recommended HTTP headers to de-activate caching are:

Cache-control: no-store
Pragma: no-cache

Below are the settings seen on many secure sites as a comparison to above and perhaps as a guide to what we should really be aiming for:

Cache-Control:max-age=0, no-cache, no-store, must-revalidate
Expires:Thu, 01 Jan 1970 00:00:00 GMT
Pragma:no-cache

HTTP Headers & Browser Implementation Differences:

Different web browsers implement caching in differing ways and therefore also implement various subtleties in their support for the cache controlling HTTP headers. This also means that as browsers evolve so too will their implementations related to these header values.

Pragma Header Setting

Use of the ‘Pragma’ setting is often used but it is now outdated (a retained setting from HTTP 1.0) and actually relates to requests and not responses. As developers have been ‘over using’ this on responses many browsers actually started to make use of this setting to control response caching. This is why it is best included even though it has been superseded by specific HTTP 1.1 directives.

Cache-Control ‘No-Store’ & ‘No-Cache’ Header Settings

A “Cache-Control” setting of private instructs any proxies not to cache the page but it does still permit the browser to cache. Changing this to no-store instructs the browser to not cache the page and not store it in a local cache. This is the most secure setting. Again due to variances in implementation a setting of no-cache is also sometimes used to mean no-store (despite this setting actually meaning cache but always re-validate, see here). Due to this the common recommendation is to include both settings, i.e: Cache-control: no-store, no-cache.

Expires Header Setting

This again is an old HTTP 1.0 setting that is maintained for backward compatibility. Setting this date to a date in the past forces the browser to treat the data as stale and therefore it will not be loaded from cache but re-queried from the originating server. The data is still cached locally on disk though and so only provides little security benefits but does prevent an attacker directly using the browser back button to read the data without resorting to accessing the cache on the file system.  For example:  Expires: Thu, 01 Jan 1970 00:00:00 GMT

Max-Age Header Setting

The HTTP 1.1 equivalent of expires header. Setting to 0 will force the browser to re-validate with the originating server before displaying the page from cache. For example: Cache-control: max-age=0

Must-Revalidate Header Setting

This instructs the browser that it must revalidate the page against the originating server before loading from the cache, i.e. Cache-Control: must-revalidate

Implementing the HTTP Header Options

Which pages will be affected?

Technically you only need to turn off caching on those pages where sensitive data is being collected or displayed. This needs to be balanced against the risk of accidently not implementing the change on new pages in the future or making it possible to remove this change accidently on individual pages. A review of your web application might show that the majority of pages display sensitive data and therefore a global setting would be beneficial. A global setting would also ensure that any new future pages added to the application would automatically be covered by this change, reducing the impact of developers forgetting to set the values.

There is a trade off with performance here and this must be considered in your approach. As this change impacts the client caching mechanics of the site there will be performance implications of this change. Pages will no longer be cached on the client, impacting client response times and may also increase load on the servers. A full performance test is required following any change in this area.

Implementing in ASP.net

There are numerous options for implementing the HTTP headers into a web application. These options are outlined below with their strengths/weaknesses. ASP.net and the .Net framework provide methods to set caching controls on the Request and Cache objects. These in turn result in HTTP headers being set for the page/application’s HTTP responses. This provides a level of abstraction from the HTTP headers but that abstraction prevents you setting the headers exactly how you might like them for full browser compatibility. The alternative approach is to explicitly set the HTTP headers. Both options and how they can be implemented are explored below:

Using ASP.net Intrinsic Cache Settings
Declaratively Set Output Cache per ASPX Page

Using the ASPX Page object’s attributes you can declaratively set the output cache properties for the page including the HTTP header values regarding caching. The syntax is show in the example below:

Example ASPX page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CacheTestApp._Default" %> 
<%@ OutputCache Duration="60" VaryByParam="None"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
<title></title> 
</head> 
<body> 
<form id="form1" runat="server"> This is Page 1.</form> 
</body> 
</html>

Parameters can be added to the OutputCache settings via the various supported attributes. Whilst this configuration allows specific targeting of the caching solution by enabling you to define a cache setting for each separate page it has the drawback that it needs changes to be made to all pages and all user controls. In addition developers of any new pages will need to ensure that the page’s cache settings are correctly configured. Lastly this solution is not configurable should the setting need to be changed per environment or disabled for performance reasons.

Declaratively Set Output Cache Using a Global Output Cache Profile

An alternative declarative solution for configuring a page’s cache settings is to use a Cache Profile. This works by again adding an OutputCache directive to each page (and user control) but this time deferring the configuration settings to a CacheProfile in the web.config file.

Example ASPX page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CacheTestApp._Default" %> 
<%@ OutputCache CacheProfile=" RHCacheProfile "%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
<title></title> 
</head> 
<body> 
<form id="form1" runat="server"> 
This is Page 1. 
</form> 
</body> 
</html>

Web.config file:

<system.web> 
<caching> 
<outputCache enableOutputCache="false"/> 
<outputCacheSettings> 
<outputCacheProfiles> 
<OutputCache CacheProfile=" RHCacheProfile"> 
<add name="RHCacheProfile" 
location="None" 
noStore="true"/> 
</outputCacheProfiles> 
</outputCacheSettings> 
</caching> 
</system.web>

This option provides the specific targeting per page and the related drawbacks of having to make changes to every page and user control. This solution does provide the ability to centralise the cache settings in one place (minimising the impact of future changes) and enables caching to be set during installation depending on target environment via the deployment process.

Programmatically Set HTTP Headers in ASPX Pages

Output caching can also be set in code in the code behind page (or indeed anywhere where the response object can be manipulated). The code snippet below shows setting the HTTP headers indirectly via the Response.Cache object:

Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1)); 
Response.Cache.SetNoStore();
Response.Cache.SetMaxAge(new TimeSpan(0,0,30));

This code would need to be added to each page and so results in duplicate code to maintain and again introduces the requirement for this to be remembered to be added to all new pages as they are developed. It results in the below headers being produced:

Cache-Control:no-cache, no-store

Expires:-1

Pragma:no-cache

 

Programmatically Set HTTP Headers in Global ASAX File

Instead of adding the above code in each page an alternative approach is to add it to the Global ASAX file so as to apply to all requests made through the application.

void Application_BeginRequest(object sender, EventArgs e)
{
	Response.Cache.SetCacheability(HttpCacheability.NoCache);
	Response.Cache.SetExpires(DateTime.Now);
	Response.Cache.SetNoStore();
	Response.Cache.SetMaxAge(new TimeSpan(0,0,30));
}

This would apply to all pages being requested through the application. It results in the below headers being produced:

Cache-Control:no-cache, no-store

Expires:-1

Pragma:no-cache

 

Explicitly define HTTP Headers outside of ASP.net Cache settings.

Explicitly Define HTTP Headers in ASPX Pages

The response object can have its HTTP Headers set explicitly instead of using the ASP.net Cache objects abstraction layer. This involves setting the header on every page:

void Page_Load(object sender, EventArgs e)
{
	Response.AddHeader("Cache-Control", "max-age=0,no-cache,no-store,must-revalidate");
	Response.AddHeader("Pragma", "no-cache");
	Response.AddHeader("Expires", "Tue, 01 Jan 1970 00:00:00 GMT");
}

Again as a page specific approach it requires a change to be made on each page. It results in the below headers being produced:

Cache-Control:max-age=0,no-cache,no-store,must-revalidate

Expires:Tue, 01 Jan 1970 00:00:00 GMT

Pragma:no-cache

Explicitly Define HTTP Headers in Global ASAX File

To avoid having to set the header explicitly on each page the above code can be inserted into the Application_BeginRequest event within the application’s Global ASAX file:

void Application_BeginRequest(object sender, EventArgs e)
{
	Response.AddHeader("Cache-Control", "max-age=0,no-cache,no-store,must-revalidate");
	Response.AddHeader("Pragma", "no-cache");
	Response.AddHeader("Expires", "Tue, 01 Jan 1970 00:00:00 GMT");
}

Again this results in the below headers being produced:

Cache-Control:max-age=0,no-cache,no-store,must-revalidate

Expires:Tue, 01 Jan 1970 00:00:00 GMT

Pragma:no-cache

Environment Specific Settings

It’s useful to be able to set the header values via configuration settings, not least to be able to test this change in a performance test environment via before/after tests.

All of the above changes should be made configurable and be able to be triggered/tweaked via the web.config file (and therefore can be modified via deployment settings).

Useful Links For More Information

Host Static HTML or WebForms Page within MVC Site

Host Static HTML or WebForms Page within MVC Site

If you need to host a static HTML page within an ASP.net MVC website or you need to mix ASP.net WebForms with an MVC website then you need to configure your routing configuration in MVC to ignore requests for those pages.

File:Belgian road sign F7.svgRecently I wanted to host a static HTML welcome page (e.g. hello.htm) on an MVC website. I added the HTML page to my MVC solution (setting it as the Visual Studio project’s start page) and configured my web site’s default page to be the HTML page (hello.htm). It tested ok at first but then I realised that it was only displaying the hello page first on debug because I’d set the page to be the Visual Studio project’s start-up page and I hadn’t actually configured the MVC routes correctly so it wouldn’t work once deployed.

For this to work you need to tell MVC to ignore the route if its for the HTML page (or ASPX page in the case of mixing WebForms and MVC). Find your routing configuration section (for MVC4 it’s in RouteConfig.cs under the App_Start folder, for MVC1,2,3 it’s in Global.asax). Once found use the IgnoreRoute() method to tell Routing to ignore the specific paths. I used this:

routes.IgnoreRoute("hello.htm"); //ignore the specific HTML start page
routes.IgnoreRoute(""); //to ignore any default root requests

Now MVC ignores a request to load the hello HTML page and leaves IIS to handle returning the resource and hence the page displays correctly.

Setting a Custom Domain Name on an Azure Web Site

Setting a Custom Domain Name on an Azure Web Site

I recently decided to add a custom domain name to a free Azure website that I use for development purposes. As the FREE Azure web site model doesn’t support custom domains (a shame but hard to complain as it’s FREE) I needed to upgrade the site to the ‘Shared’ mode. This is easily done by the Scaling button in the azure portal.

Firstly however I needed to link my current azure web site to sit under a different subscription to the one I used to set it up. The problem is that cannot move sites between subscription models yet (please fix this Microsoft). To get around this I needed to create a new website under the correct subscription and then publish my web site code to it. Luckily this is easy to do as it’s just a basic website but I can imagine that this could be painful if you have a bunch of storage accounts or a database to re-create.

Using the Azure Portal, creating a new site is a simple process Click +NEW at the bottom of the portal for the menu shown below:

image

Once created all I needed to do was download a Publish profile (see this tutorial link for how to publish to Azure) for the new site for Visual Studio to use. Once downloaded I opened my VS2012 solution and brought up the Publish dialog. I pointed it to the new Publish profile file and clicked Publish. In just a few seconds I’ve got a new Azure web site up and running with my existing MVC web application. This was very smooth, with no change to config or code required. The sheer simplicity of this impressed me as I was short on time.

Next I needed to allocate my custom domain which as previously mentioned is not available for FREE websites so i needed to upgrade to SHARED mode. From the Azure portal >web site configuration > scale > click SHARED (remember this model incurs a cost).

image

Once upgraded I could then immediately select DOMAINS and set up my CNAME and A record references, for more information see this useful link (configuring a custom domain name for a Windows Azure web site). It’s worth reading the comments on the post too as it covers issues with registering the domain without the WWW subdomain.

Once the DNS entries had propagated I had my existing site up and running under a custom domain running within a shared Azure instance, all with very little effort.