Using the new Windows Azure Tools v1.4 for VS2010

The new Windows Azure Tools for v1.4 (August 2011) for VS2010 have just been released.  You can download them using Web Platform Installer here. This latest version of the tools introduces several new features as follows:
  1. Support for Multiple Service Configurations
  2. Profiling support for Windows Azure apps running in Windows Azure
  3. MVC 3 web role support
  4. Package validation
Note: Profiling is only supported in VS 2010  Ultimate+Premium.  All others are available from Visual Web Developer 2010 and up.
This post will take a brief look at the benefits each of these new features bring to you – the developer :)

 

Multiple Service Configurations

Gone are the days of having to change your settings in your ServiceConfiguration.cscfg when you switch from debugging your local cloud+storage emulator to publishing up to Windows Azure.  For example in your development environment for:
  1. local debug you may want to:
    • utilize 1 instance of your web/worker role
    • use the local storage emulator
  2. whereas in Windows Azure you may want to:
    • utilize 4 instances of your web/worker role
    • use a production Windows Azure storage account
To achieve this using the new multiple service configurations is easy.
  1. Create a new Windows Azure project with an arbitrary web or worker role.
    • File > New Project > Cloud > Windows Azure Project
    • Select a web or worker role and press OK
  2. Observe that the ServiceConfiguration.cscfg is now split by default into two files:
    • ServiceConfiguration.Local.cscfg – default used when debugging in VS
    • ServiceConfiguration.Cloud.cscfg – a config you can use on publish
  3. To configure each individual configuration with the settings we desired above.
    • Double click on the WorkerRole1 in the roles folder of the cloud project
    • then and select the Service Configuration dropdown for Cloud
    • Select Service Configuration Profile

    • Set the desired settings for your Cloud profile ServiceConfiguration.Cloud.cscfg

  4. You can then repeat the above for your Local configuration profile to setup and set the desired settings for ServiceConfiguration.Local.cscfg
  5. The net result is that both ServiceConfiguration.Cloud.cscfg and ServiceConfiguration.Local.cscfg will now have their independent settings as follows:
      Independent config in ServiceConfiguration.Cloud.cscfg

      Independent config in ServiceConfiguration.Cloud.cscfg

      Independent config in ServiceConfiguration.Local.cscfg

      Independent config in ServiceConfiguration.Local.cscfg

  6. When you hit debug now the ServiceConfiguration.Local.cscfg is used and when you hit publish you can select which Config you would like to use:

Overall its quite an easy experience to configure and use multiple Service Configuration profiles for your different environments.  Please note that you can also rename and add additional Service Configuration profiles perhaps such that you would have a config for Local, Staging and Prod.  For more detail on how to work with Service Configuration files please see Configuring a Windows Azure Application.

Profiling Support

This is an incredibly useful tool for any Windows Azure developer as it enables you to profile your Windows Azure application that’s running up in Windows Azure.  The information gathered can help analyze any performance issues you may be facing.  When you publish your application from VS you are able to specify your profiling options that will apply for the profiling session and results can be pulled for each instance.
The supported profiling options are as follows:
  1. CPU Sampling – Monitor CPU-bound applications with low overhead
  2. Instrumentation – Measure function call counts and timing
  3. .NET Memory Allocation (Sampling) – Track managed memory allocation
  4. Concurrency -Detect threads waiting for other threads
In this segment I will demonstrate how to configure a profiling session for a Windows Azure Application:
  1. Open your existing cloud project and right click on the windows azure cloud project and select Publish
  2. Select the Enable profiling option on the publish page and click settings
  3. Select the type of profiling you wish to perform in this case .NET Memory Allocation
  4. Note: Checking the Enable Tier Interaction Profiling option captures additional information about execution times of synchronous ADO.NET calls in functions of multi-tiered applications that communicate with one or more databases.  With the absence of a SQL Profiler in SQL Azure this feature is useful for those developers who want to gain some insight into what queries or stored procedures are running slowly.
  5. Press OK.
  6. Once the deployment is complete and the application has been running for a period of time you can go and download the captured profiling report.
  7. To download the profiling report
    • Select View > Server Explorer
    • Expand Windows Azure Compute
    • Expand the hosted service
    • Right click on the Instance that you want do download the profiling report from and press View Profiling Report
  8. Once the report is downloaded it will open in VS and as you can see the CPU is maxing out
  9. If we change the Current View dropdown to Allocation we can quickly identy a problem method that is using excessive amounts of memory
  10. and finally if we right click and select View Source on the method of interest we can see the offending line causing the allocations
What an awesome tool.  I look forward to digging deeper into the capabilities provided by for Windows Azure Profiling. In the meantime for more information please see – Profiling a Windows Azure Application

 

MVC 3 Web Role Support

ASP .NET MVC 3 web roles are now supported out of the box with the new tools.  You can select ASP .NET MVC 3 from the new Windows Azure project dialog and the required assemblies used by ASP .NET MVC 3 are set to copy local for you.  This results in these assemblies being deployed up to windows azure when you publish your application thus ensuring your MVC 3 application will start when deployed. I know a lot of you are probably thinking Eureka right now and those that may get a little bit too excited may even verbalize it, I know I did :)

To create a new Windows Azure ASP .NET MVC 3 application:

  1. File > New Project > Cloud > Windows Azure Project
  2. Select ASP .NET MVC 3 Web Role, press the > button followed by OK
  3. In the ASP .NET MVC 3 project dialog select settings to suit your preferences and press ok
  4. In solution explorer observe that all the references assemblies for ASP .NET MVC 3 that are not in the GAC in the current Windows Azure gues OS have had their Copy Local property set to true.  The below image shows and example of one of the required reference assemblies that is automatically set to copy local so you dont actually have to do anything :)

From here on in all you have to do is start coding :) – For more information on ASP .NET MVC 3 see this and for a detailed walkthrough of ASP .NET MVC 3 on Windows Azure see this post by Nathan Totten

Package Validation

Last but definitely not least is improved package validation. When you select to create a package or publish your Windows Azure application. Additional warnings or errors are now provided in VS to enable you to fix the problem before you package or publish it.  This as you know will be a great timesaver for details of what package validations are performed please see Troubleshooting Package Validation Errors and Warnings

Time to Download

All in all its an excellent new set of features that focus on improving your productivity and make your dev life a whole lot easier. If you have not already then now would be the time to download using Web Platform Installer :)

happy coding,

Nick

ASP .NET MVC 3 Beta Deploy to Azure Cycles

If you have just downloaded ASP .NET MVC 3 Beta and upgraded your ASP .NET MVC 2 website then tried to deploy on Azure and found that your deploy is cycling this will likely solve your problem.

Recall while upgrading for MVC 3 Beta you update your project to reference System.Web.Mvc.dll (v3.0.0.0), System.WebPages.dll and System.Web.Helpers.dll – well the likely cause of the issue is you have not updated those three assembly references to copy local i.e Right Click >> Copy Local = True. If you were to deploy at this stage you would still have the cycle issue.  With a quick review of intellitrace logs you you have to add a reference to WebMatrix.Data.dll, System.Web.WebPages.Razor.dll and Microsoft.Web.Infrastructure.dll all of which when run on local are retrieved from the GAC. Therefore the full list of assemblies to copy local becomes:

  • System.Web.Mvc.dll (v3.0.0.0)
  • System.WebPages.dll
  • System.Web.Helpers.dll
  • WebMatrix.Data.dll
  • System.Web.WebPages.Razor.dll
  • Microsoft.Web.Infrastructure.dll
  • Hope this saves you some time
    Nick

    A first look at the ASP .NET MVC 3 WebGrid

    I just installed ASP .NET MVC 3 Beta. This post provides a brief introduction to the new WebGrid.
    Note:

    • At the time of writing the ASP .NET MVC 3 was in Beta
    • I am not yet using Razor for my view markup
    • Sorry about the formatting in the syntax highlighting on this one
    1. How to add an ActionLink Edit column to the ASP .NET MVC 3 WebGrid.
      • To start lets look at a cut down version of the original ASP .NET MVC 2 View generated (except the delete action) using the built in scaffolding:
      • <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<ABC.Web.Models.ModelX>>" %>
        <table>
        <tr>
        <th></th>
        <th>
           Title
        </th>
        <th></th>
        </tr>
        <% foreach (var item in Model) { %>
           <tr>
           <td>
              <%: Html.ActionLink("Edit", "Edit", new { id=item.Id }) %>
           </td>
           <td>
              <%: item.Title %>
           </td>
           <td>
              <a onclick="deleteRecord('Cart', '<%= item.Id %>')" href="JavaScript:void(0)">Delete</a>
           </td>
           </tr>
           <% } %>
        <p>
        <%: Html.ActionLink("Create New", "Create") %>
        </p>
      • Replacing this with the ASP .NET MVC 3 Beta WebGrid can be performed as follows:
      • <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<ABC.Web.Models.ModelX>>" %>
        <%
        var grid = new System.Web.Helpers.WebGrid(Model, new List<string>(){"Title"});
        %>
        <%= grid.GetHtml(columns: grid.Columns(
              grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.Id })),
              grid.Column("Title"),
              grid.Column(format:(item) => Html.ActionLink("Delete", "Delete", null, new {onclick=string.Format("deleteRecord('Cart', '{0}')", item.Id), @class="Delete", href="JavaScript:void(0)"}))
        )
        ) %>
        <p>
        <%: Html.ActionLink("Create New", "Create") %>
        </p>

        The important point to note here is that to get your Edit ActionLink you need to provide a Column definition with the format parameter specified such that it returns your ActionLink i.e

        grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.Id }))
    2. How to enable/disable the pager and change the page size.
    3. Straight out of the box the WebGrid supports paging which by default is enabled with a page size of 10 but can be configured using the rowsPerPage and canPage attributes as follows:

      <%
      var grid = new System.Web.Helpers.WebGrid(Model,
                   columnNames: new List<string>(){"Title"},
                   rowsPerPage:5,
                   canPage:true);
      %>
    4. How to emit CSS class attributes to your table
    5. The last thing worth mentioning in this introductory post is that the css class can also be specified for the table using the following parameters tableStyle, headerStyle, footerStyle, rowStyle and alternateRowStyle style as follows:

      <%= grid.GetHtml(
         tableStyle: "table",
         headerStyle: "header",
         footerStyle: "footer",
         rowStyle: "row",
         alternatingRowStyle: "alt",
         columns: grid.Columns(
            grid.Column(format: (item) => Html.ActionLink("Edit", "Edit", new { id = item.Id })),
            grid.Column("Title"),
            grid.Column(format:(item) => Html.ActionLink("Delete", "Delete", null, new {onclick=string.Format("deleteRecord(Cart, '{0}')", item.Id), @class="Delete", href="JavaScript:void(0)"}))
      )
      ) %>

    Happy Coding,
    Nick

    How to Enable IntelliTrace on Windows Azure

    If your Azure project targets the .NET framework 4.0 you can utilize IntelliTrace to help debug your application. This post briefly covers how to enable and retrieve your IntelliTrace log.  The issue I was debugging in this scenario was a service I was deploying and ASP .NET MVC website it was initializing /stopping / initializing / stopping repeatedly during the deploy to Azure.

    1. When publishing your service select the Enable IntelliTrace for .NET 4 roles checkbox
    2. Enable IntelliTrace

      Enable IntelliTrace

    3. Let the instance deploy and cycle through the initializing and stopping states
    4. Then to download your IntelliTrace log.  In Server Explorer expand your windows Azure hosted service node, right click on your hosting account and select View IntelliTrace log.  This will be downloaded Async.
    5. View Intellitrace

      View Intellitrace

    6. Once the log is retrieved you can review the exceptions
    7. IntelliTrace

      IntelliTrace

    8.  In this case I had not set the System.Web.MVC assembly to copy local and re-deployed.  Job done.

    Nick

    ASP .NET Ajax ActionLink with UpdateTargetId callback

    1. The Ajax.ActionLink available withing ASP.NET AJAX can be used to invoke controller actions and update your form asynchronously based on the response. This brief post will describe at how to do this within the context of an Approvals table.
    2. In yoru ASP .NET MVC 2 Web Application add a references to the ASP.NET AJAX library scripts into your Views/Shared/Site.Master at the end of your head element. 
    3. <head>
      ...
      <script src="/Scripts/MicrosoftAjax.js" type="text/javascript"/>
      <script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"/>
      </head>
      
    4. Update your view
    5. Tip: To improve performance these files are available on the Microsoft CDN which means if you use this they should be downloaded faster from the appropriate node based on user location as compaired to from your own web server.

    6. Add your Ajax.ActionLinks.  In  this case we want one to Approve and one to Reject.  On success we want the cell to the left of the ActionLinks to be updated to contain the updated status. 
    7. <%@ Page Title="" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Dummy.Web.Models.SomeModel>>" %>
      
      <asp:Content ContentPlaceHolderID="TitleContent" runat="server">
       Index
      </asp:Content>
      
      <asp:Content ContentPlaceHolderID="MainContent" runat="server">
       <table>
              <tr>
                  <th>
                      Name
                  </th>
                  <th>
                      Caption
                  </th>        
                  <th>
                     Approved/Rejected
                  </th>         
              </tr>
      
          <% foreach (var item in Model) { %>  
              <tr>
                  <td>
                      <%: item.Name %>
                  </td>
                  <td>
                      <%: item.Caption %>
                  </td>        
                  <td id="status_<%: item.Id.ToString() %>>
                       <%: item.Status %>
                  </td>
                  <td>
                      <%: Ajax.ActionLink("Approve", "ApproveAction", new { id= item.Id }, new AjaxOptions() { UpdateTargetId = string.Format("status_{0}", item.Id) })%>
                      <%: Ajax.ActionLink("Reject", "RejectAction", new { id= item.Id }, new AjaxOptions() { UpdateTargetId = string.Format("status_{0}", item.Id) })%>
                  </td>        
              </tr>
        
          <% } %>
      </asp:Content>
      

      Note: the Id of the cell that we want to update afterwards is set dynamically as follows <td id=”status_<%: item.Id.ToString() %>> then the ActionLink parameters state Text of Approve, call the Controllers ApproveAction with the parameter id set as a value of item.Id and the result of the ApproveAction is to update the target cell with id string.Format(“status_{0}”, item.Id)

    8. Update your corresponding controller to define the ApproveAction and RejectAction methods:
    using System;
    using System.Web.Mvc;
    using Dummy.Web.Models;
    using Dummy.Web.Models.Common;
    
    namespace Dummy.Web.Controllers
    {
        [Authorize]
        public class ApprovalsController : AntiForgeryController
        {
            ISomeRepository _someRepository;
    
            public ApprovalsController():this(new someRepository()){ }
    
            public ApprovalsController(ISomeRepository someRepository)
            {          
                _someRepository = someRepository);
            }
            //
            // GET: /Approvals/
            public ActionResult Index()
            {
                return View(_someRepository.GetItemsForApproval(20));
            }
    
            [HttpPost]      
            public string ApproveAction(Guid id)
            {
               return UpdateAction(id, ApprovalStatusType.Approved);
            }
    
            [HttpPost]      
            public string RejectAction(Guid id)
            {
               return UpdateAction(id, ApprovalStatusType.Rejected);
            }
    
            protected string UpdateAction(Guid id, ApprovalStatusType status)
            {
    
               string result = "Error: Unable to Update";
                if (_someRepository.UpdateStatus(id, ApprovalStatusType.Approved))
                {
                    result = ApprovalStatusType.Approved.ToString();
                }
    
                return result;
            }
        }
    }
    

    Thats about all that is required to add an Ajax.ActionLink that can be used to invoke controller actions and update your form asynchronously based on the controllers response.

    Nick

    ASP .NET MVC datetime editor template using jQuery datepicker

    This post details how to create an ASP .NET MVC editor template for the DateTime? datatype which will show a jQuery datepicker: 

    1.  Add the the jQuery UI js, css and Images to solution:
      • I have put the jQuery images and css under /Content/Images and /Content respectively.  
      • and the js under the /Scripts
    2. Update your site.master to reference the js and css:
        <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
        <link href="../../Content/jquery.ui.all.css" rel="stylesheet" type="text/css" />
    
        <script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"/>
        <script src="../../Scripts/jquery.ui.core.js" type="text/javascript" />
        <script src="../../Scripts/jquery.ui.widget.js" type="text/javascript" />
        <script src="../../Scripts/jquery.ui.datepicker.js" type="text/javascript" />
    
        <script src="/Scripts/MicrosoftAjax.js" type="text/javascript" />
        <script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript" />
        <script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript" /> 
    1. Create the Editor Template:
      • Create the following folder structure if not already present Views/Shared/EditorTemplates/
      • Add a ViewUserControl called DateTime.ascx and use the following as thee content.
    2. Note: the htmlAttributes parameter is new { @class = “dp”}) this will render a class=’dp’ attribute for later use by jQuery to identify where datepickers are required

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
    <%: Html.TextBox("",  String.Format("{0:yyyy-MM-dd}", Model.HasValue ? Model : DateTime.Today), new { @class = "dp"})%>
    
      Note: that I have set this to accept a nullable datetime – DateTime? and provided the default value of today if the date way empty.

    1.  JQuery datepicker script:
      • Place the following jQuery preferably in a Common.js or in the head of your page or site master wher ethe control will be displayed.
    <script  type="text/javascript">
     $(document).ready(function () {
     $(".dp").datepicker({
                 changeMonth: true,
                 changeYear: true,
                 dateFormat: 'yy-mm-dd'
                       });
                    });
      </script>

    Note: that we are searching for anything using the “.dp” class and supplying arguments to the datepicker to format the date and provide dropdowns for year and month.

    At this point any defined view that you have that is rendering the DateTime should now show the editor as the DateTime.ascx editor template

    E.g I have a view binding to my Model and one of the properties called StartDate is DateTime?  the view for displaying this model contains
        

     
    <div class="editor-label">
        <%: Html.LabelFor(model => model.StartDate) %>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(model => model.StartDate)%>
        <%: Html.ValidationMessageFor(model => model.StartDate) %>
    </div>

    Upon rendering the DateTime editor template is applied and hey presto:

    Nick

    Debugging WCF Data Services – An error occured while processing this request

    Issue: I was calling my WCF Data Service today and was getting a NotSupportedException with an InnerException of “An error occured while processing this request” and no further detail which is not very helpful for debugging.

    Solution: So the workaround for this is to set UseVerboseErrors in your service in your service initialization method like so

    public static void InitializeService(DataServiceConfiguration config)
    {
       config.UseVerboseErrors = true;
    
      .....
    
    }

    This however is not good for production scenarios as we don’t want Verbose errors going back to clients.  Given that it is hardcoded to true ideally you would want to be able to configure this in your web.config.  There is no section within the web.config supported out of the box for this.  So you can use an appSetting or create your own custom section.

    after building and deploying the service you should now get the full detail in your exception.InnerException.Message E.g

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
      <code></code>
      <message xml:lang="en-AU">An error occurred while processing this request.</message>
      <innererror>
        <message>Unable to update the EntitySet 'Posts' because it has a DefiningQuery and no &lt;InsertFunction&gt; element exists in the &lt;ModificationFunctionMapping&gt; element to support the current operation.</message>
        <type>System.Data.UpdateException</type>
        <stacktrace>   at System.Data.SqlClient.SqlGen.DmlSqlGenerator.ExpressionTranslator.Visit(DbScanExpression expression)&#xD;
       at System.Data.SqlClient.SqlGen.DmlSqlGenerator.GenerateInsertSql(DbInsertCommandTree tree, SqlVersion sqlVersion, List`1&amp; parameters)&#xD;
       at System.Data.SqlClient.SqlProviderServices.CreateCommand(DbProviderManifest providerManifest, DbCommandTree commandTree)&#xD;
       at System.Data.Mapping.Update.Internal.UpdateTranslator.CreateCommand(DbModificationCommandTree commandTree)&#xD;
       at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.CreateCommand(UpdateTranslator translator, Dictionary`2 identifierValues)&#xD;
       at System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator translator, EntityConnection connection, Dictionary`2 identifierValues, List`1 generatedValues)&#xD;
       at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)&#xD;
       at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)&#xD;
       at System.Data.Services.Providers.ObjectContextServiceProvider.SaveChanges()&#xD;
       at System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)&#xD;
       at System.Data.Services.DataService`1.HandleRequest()</stacktrace>
      </innererror>
    </error>
    

    Nick

    Some first time Azure deployment findings

    Today I completed my first couple of deployments of an OData service to Windows Azure hosted in the Geographic Location of “Anywhere Asia”.

    What I liked about the dev experience – As  a complete Azure newb I was able to do the following in under a day :

    1. Migrate an existing SQL 2008 R2 DB to Azure SQL
    2. Connect remotely to the new Azure SQL DB using SQL Management Studio
    3. Create and deploy an OData Service that is fed from the Azure SQL DB
    4. Get some blobs into the Blob storage
    5. Consumed the OData service and Blob from a Windows Phone 7 Application – All I had to do was update the client I created here Consuming an OData service from windows phone 7 to point my TestClient URI to the cloud service rather then my local. 
    6. 16 Months Free*

    What I didn’t like:

    1. Could not find support in Visual Studio 2010 to deploy to SQL Azure directly.  If anyone is aware how please throw a link at me.  I had to gen deployment scripts using SQL Management Studio.  VS 2010 Data compare did not work when compairing between SQL Server 2008 R2 and SQL Azure. Note I did find this project on codeplex which might be handy – SQL Azure Migration Wizard v3.3.5

    2. newsequentialid() is not supported in SQL Azure - makes sense given that the sequential id is partially generated based on the network card therefore does not fit well with sql azure running across multiple machines.  But the issue is to get it up and running quickly i had to update to use newid() so now not sure how fragmented my indexes are going to become and this will have an impact on my insert performance so I will need to revise this.

    3. Unable to upload to blob storage from within Server Explorer.  You can only view your blobs as per image

      below and I had to code a client application just to upload the simple HelloWorld test file you see below :( … Would be great to see an Upload option in the context menu.

      Server explorer azure no blob upload
      Server explorer azure no blob upload
    4. Time to taken to deploy the service that contained only a simple Entity Model and single OData service was quite a while.  But when you look at whats going on under the hood its pretty damn quick althought it would be great to have the output window for the azure deployment indicate exactly whats happening rather then just a few initialising, busy, running statements etc.
    5. If anyone has any helpful links to the issues above – please feel free to post the links in the comments.
    Nick

    How to HtmlEncode user content to avoid cross site scripting attacks

    Issue:  So you have put together a website that enables users to enter content that somewhere along the line renders to the screen.  Take for example www.FishingTribute.com.   

    FishingTribute.com

    Fishing Tribute

     Somewhere along the way a user uploads an image and injects some javascript into a label that is rendered back to the page.  The problem is labels, image text and the like are scatterd throughout the site and you dont really want to search through and HTML encode the text of every control.   

     Solution: Well one simple answer is to come up with your own control that HTML encodes the text as it renders to the page. Create a new assembly so that you can re-use it across all your sites. The following example creates a SecureLabel control.  

    using System;
    using System.Web;
    using System.Web.UI.WebControls;
    
    namespace Tribute.Core.Secure
    {
        public class SecureLabel: Label
        {
            private bool _XSSEncode = true;
    
            protected override void Render(System.Web.UI.HtmlTextWriter writer)
            {
                if(XSSEncode && !String.IsNullOrEmpty(this.Text))
                {
                    this.Text = HttpUtility.HtmlEncode(this.Text);
                }
    
                base.Render(writer);
            }
    
            public bool XSSEncode
            {
                get { return _XSSEncode; }
                set { _XSSEncode = value; }
            }
        }
    } 

    Lets look at the code SecureLabel inherits from Label (the one we are currently using on the page). A public XSSEncode property is available to optionally change the the default value to true (i.e always html encode unless otherwise specified).    

     Override the Render method of the Label base class is and HttpUtility.HtmlEncode the text of the control if XSSEncode is true.  

    But we are still not quite there yet, just as I did not want to go through my whole websites codebase and add HttpUtility.HtmlEncode(…) everywhere I dont want to go through my whole website and replace all my Label controls with SecureLabel controls. The solution is simple use the <controlls> and <tagMapping> within your web.config to register the controls and map the .net WebControl to the newly created control as per the following  

    <system.web>
       <pages >
         <controls>
               …
               <add tagPrefix=“asp“ namespace=“Tribute.Core.Secure“ assembly=“Tribute.Core“/>
          </controls>
         <tagMapping>
               <add tagType=“System.Web.UI.WebControls.Label“ mappedTagType=“Tribute.Core.Secure.SecureLabel“/>
               <add tagType=“System.Web.UI.WebControls.Image” mappedTagType=“Tribute.Core.Secure.SecureImage“/>
          <tagMapping/>
      <pages/>
    <system.web/>

    There you have it – a low effort no fuss solution :)

    A heads up from Phil on Literals usage – use the mode=”Encode” property

    www.FishingTribute.com goes live

    Here we go, another website rolled out for Alpha testing – Enter http://www.FishingTribute.com/ - FishingTribute.com is a site created to allow all to share pictures of their catch with other fishing enthusists around the world, its intention is to be a fun site full of user submitted images and comments. Check it out, join up and have some fun sharing what you may spend your catch. Its early days and the site is still in Alpha with a bunch more functionality on the way…