ASP.Net C# Override Render event to get and manipulate page content before it's rendered

Here's an easy way to intercept the content that an ASP.Net page is going to render and send back to the browser.
   protected override void Render(HtmlTextWriter Writer)  
   {  
      // variables
      string Content = string.Empty;  
   
      // get the fully rendered content of this page so we can do some additional translations if necessary  
      using (StringWriter StringWriter = new StringWriter())  
      {  
         using (HtmlTextWriter HtmlTextWriter = new HtmlTextWriter(StringWriter))  
         {  
            // render current page content to temp writer  
            base.Render(HtmlTextWriter);  
   
            // close writer  
            HtmlTextWriter.Close();  
   
            // get content  
            Content = StringWriter.ToString();  

            // DO SOMETHING WITH THE CONTENT
         }  
      }  

      // render content
      Writer.Write(Content);
   }

Using the override keyword for the Render event lets you get and manipulate the content before it's rendered. Using the example above, the Content string variable will hold the content that will be rendered back to the browser. Now you could manipulate the content before it is rendered. A good example would be some kind of string replacement. Say for example you want to define a custom pattern and use it through your pages, content, resource files, and such. In that case you could use the following code where the DO SOMETHING WITH THE CONTENT comment is.

   // look for <translate></translate> pattern so we can translate them on the fly  
   foreach (Match m in Regex.Matches(Content, @"<translate>(.*?)</translate>", RegexOptions.IgnoreCase))  
   {  
      // get the pattern
      // e.g. <translate>lblFirstName</translate>   
      string Pattern = m.Value.ToLower();

      // remove the pattern so you are left with just the ID
      // e.g. lblFirstName
      string ID = Pattern.ReplaceValue("<translate>", string.Empty).ReplaceValue("</translate>", string.Empty);

      // do some kind of lookup with the ID
      // e.g. This could be something as simple as getting a value from a resource file for a specific language
      string Translation = "Lookup value for the current ID";
   
      // do a string replacement on the Content variable replacing the pattern with your translation
      Content = Content.ReplaceValue(Pattern, Translation);
   }  

The above code is dependent upon a simple ReplaceValue extension method:
   public static string ReplaceValue(this string Value, string Pattern, string Replacement)  
   {  
      return Regex.Replace(Value, Regex.Escape(Pattern), Replacement, RegexOptions.IgnoreCase);  
   }  

This is a simplified version of a solution that I use regularly, and it works really well. This idea sort of evolved over time to handle more complex scenarios were you don't always have the luxury of using simpler techniques. For example, at first glance you might just think about using a simple resource file on your ASPX page. That can work for a lot of situations. Another thought would be to use a custom user control where you can define a "key" attribute and do your resource lookup within the user control. Again, a very good solution that can cover most situations; however, this particular pattern replacement technique allows you to handle other situations where you have data that is not directly within your ASPX page, for example, other resource files, or data from a database, etc.

The pattern can be used literally anywhere on the page. Whether it's in your JavaScript, HTML, or even part of a more complex ASP.Net web control, for example:

JavaScript:
 alert("<translate>FirstNameRequired</translate>");  

HTML:
 <div><translate>lblDisclaimer</translate></div>  

GridView:
 <asp:BoundField DataField="FirstName" HeaderText="<translate>lblFirstName</translate>" HtmlEncode="false" />  

How it's used is really limitless, and for language driven websites, it can be a really nice way to make things more generic and flexible.

ASP.Net C# Creating an AutoFocus property in your Master Page

Recently I posted about Accessing Master Page Controls from Content Pages. This same technique can be used to create an AutoFocus property that you can use generically from your content pages.

Base.Master
   <!-- auto focus -->  
   <asp:PlaceHolder ID="pnlAutoFocus" runat="server">  
     <script language="javascript" type="text/javascript">  
       $(document).ready(function () {  
         $(':input:enabled:visible:not(.noautofocus):first').focus();  
       });  
     </script>  
   </asp:PlaceHolder>  

Notice we're using jQuery and we're targeting the first input control that is enabled, visible, and does not have a noautofocus class. The noautofocus class allows us to still use the AutoFocus feature on a page, but exclude certain controls if necessary, for example:
 <asp:DropDownList ID="ddlState" CssClass="form-control noautofocus" ClientIDMode="Static" runat="server" />  

Next we expose the AutoFocus property in the Base.Master code-behind.

Base.Master.cs
     public bool AutoFocus  
     {  
       get  
       {  
         return pnlAutoFocus.Visible;  
       }  
       set  
       {  
         pnlAutoFocus.Visible = value;  
       }  
     }  

Now you can access the AutoFocus property from your content pages like so.

Test.aspx
  <%@ Page Language="C#" MasterPageFile="~/Base.Master" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="Sandbox.Web.Test" %>   
  <%@ MasterType VirtualPath="~/Base.master" %>  

Test.aspx.cs
   private void Page_PreLoad(object sender, System.EventArgs e)  
   {  
      // auto focus  
      Master.AutoFocus = true;  
   }  

JSFiddle:
http://jsfiddle.net/mpavey/4r1ttfgy/

Why use this approach? Well for me it allows me to keep things generic. Sure you could manually set the focus of the appropriate web control from page to page in its respective code-behind (or with JavaScript); however, this approach lets you just build the form and basically will focus things for you automatically, and you only have to handle exceptions, which can be accomplished with the noautofocus class or by disabling the AutoFocus property for the entire page.

ASP.Net MVC Using a Base Controller to access the current HTTP request

I'm a big fan of using "base" classes. If I'm working with an ASP.Net web project, I have a BasePage class that all content pages inherit from. If I'm working with a model layer, I have a BaseModel class that all model objects inherit from. If I'm working with a data layer, I have a BaseDB class that all data layer classes inherit from. So when it comes to MVC and dealing with controllers it's no different for MVC controllers or API controllers.

In this example I define a BaseController class that inherits from System.Web.Http.ApiController. This example also shows you how you can access the System.Web.HttpRequest object for the current HTTP request to access information like QueryString, IP Address, URL information, UserAgent information, browser information, and more.
 Public Class BaseController  
   Inherits System.Web.Http.ApiController  

Then you can expose whatever properties or methods you want in your BaseController class.
   Public ReadOnly Property QueryString() As String  
     Get  
       Try  
         Return DirectCast(Request.Properties("MS_HttpContext"), HttpContextBase).Request.QueryString.ToString  
       Catch ex As Exception  
         Return String.Empty  
       End Try  
     End Get  
   End Property  
   
   Public ReadOnly Property IPAddress() As String  
     Get  
       Try  
         Return DirectCast(Request.Properties("MS_HttpContext"), HttpContextBase).Request.UserHostAddress  
       Catch ex As Exception  
         Return String.Empty  
       End Try  
     End Get  
   End Property  
   
   Public ReadOnly Property UrlRequest() As String  
     Get  
       Try  
         Return DirectCast(Request.Properties("MS_HttpContext"), HttpContextBase).Request.Url.AbsoluteUri  
       Catch ex As Exception  
         Return String.Empty  
       End Try  
     End Get  
   End Property  
   
   Public ReadOnly Property RawUrl() As String  
     Get  
       Try  
         Return DirectCast(Request.Properties("MS_HttpContext"), HttpContextBase).Request.RawUrl  
       Catch ex As Exception  
         Return String.Empty  
       End Try  
     End Get  
   End Property  
   
   Public ReadOnly Property UrlReferrer() As String  
     Get  
       Try  
         Return DirectCast(Request.Properties("MS_HttpContext"), HttpContextBase).Request.UrlReferrer.AbsoluteUri  
       Catch ex As Exception  
         Return String.Empty  
       End Try  
     End Get  
   End Property  
   
   Public ReadOnly Property UserAgent() As String  
     Get  
       Try  
         Return DirectCast(Request.Properties("MS_HttpContext"), HttpContextBase).Request.UserAgent  
       Catch ex As Exception  
         Return String.Empty  
       End Try  
     End Get  
   End Property  
   
   Public ReadOnly Property Crawler() As Boolean  
     Get  
       Try  
         Return DirectCast(Request.Properties("MS_HttpContext"), HttpContextBase).Request.Browser.Crawler  
       Catch ex As Exception  
         Return False  
       End Try  
     End Get  
   End Property  

This same concept also works for System.Web.Mvc.Controller.
 Public Class BaseController  
   Inherits System.Web.Mvc.Controller  

In the case of System.Web.Mvc.Controller, we can access the current HTTP request directly from the Request object, without needing to look at MS_HttpContext.
     Public ReadOnly Property QueryString() As String  
       Get  
         Try  
           Return Request.QueryString.ToString  
         Catch ex As Exception  
           Return String.Empty  
         End Try  
       End Get  
     End Property  
   
     Public ReadOnly Property IPAddress() As String  
       Get  
         Try  
           Return Request.UserHostAddress  
         Catch ex As Exception  
           Return String.Empty  
         End Try  
       End Get  
     End Property  
   
     Public ReadOnly Property UrlRequest() As String  
       Get  
         Try  
           Return Request.Url.AbsoluteUri  
         Catch ex As Exception  
           Return String.Empty  
         End Try  
       End Get  
     End Property  
   
     Public ReadOnly Property RawUrl() As String  
       Get  
         Try  
           Return Request.RawUrl  
         Catch ex As Exception  
           Return String.Empty  
         End Try  
       End Get  
     End Property  
   
     Public ReadOnly Property UrlReferrer() As String  
       Get  
         Try  
           Return Request.UrlReferrer.AbsoluteUri  
         Catch ex As Exception  
           Return String.Empty  
         End Try  
       End Get  
     End Property  
   
     Public ReadOnly Property UserAgent() As String  
       Get  
         Try  
           Return Request.UserAgent  
         Catch ex As Exception  
           Return String.Empty  
         End Try  
       End Get  
     End Property  
   
     Public ReadOnly Property Crawler() As Boolean  
       Get  
         Try  
           Return Request.Browser.Crawler  
         Catch ex As Exception  
           Return False  
         End Try  
       End Get  
     End Property  

Now when you create your individual Web or API controllers, you can inherit from the BaseController and access the exposed properties or methods easily.

ASP.Net Intercept postback event

Ever needed to intercept the ASP.Net postback event from the client-side using javascript so you can override or customize something? Here's a simple way to do it.

Code:
   ...  
   
   <!-- intercept postback event -->  
   <script language="javascript" type="text/javascript">  
     // get reference to original postback method before we override it  
     var __doPostBackOriginal = __doPostBack;  
   
     // override  
     __doPostBack = function (eventTarget, eventArgument) {  
       // show progress modal  
       ShowProgress();  
   
       // postback  
       __doPostBackOriginal.call(this, eventTarget, eventArgument);  
     }  
   </script>  
 </body>  
 </html>  

First you need to get a reference to the original __doPostBack event and save it in the __doPostBackOriginal variable. This is necessary so you can trigger it later.

Once you have the reference to the original postback event you can override __doPostBack. This is where you'll want to put your custom code. In this example, I call a ShowProgress() method. This is where I trigger a custom bootstrap modal so for any postback you see a progress spinner.

After you've added your custom override you call __doPostBackOriginal.call(this, eventTarget, eventArgument); to trigger the original postback event.

It's worth noting that the __doPostBack javascript event is only rendered when it is needed. It will be rendered by ASP.Net whenever you add a web server control to your form, with the exception of Button and ImageButton controls. For buttons you will need to add your own OnClientClick to handle client-side events.

ASP.Net C# Accessing Master Page Controls from Content Pages

This is a pretty simple task, but one I use frequently. Often times I have controls in my master page that I want to access or somehow control differently from page to page. So here is a very simple example of how to accomplish that.

Base.Master
   <asp:PlaceHolder id="pnlDoNotIndex" visible="false" runat="server">  
     <meta name="robots" content="noindex" />  
   </asp:PlaceHolder>  

Base.Master.cs
     public bool DoNotIndex
     {  
       get { return pnlDoNotIndex.Visible; }  
       set { pnlDoNotIndex.Visible = value; }  
     }  

Test.aspx
 <%@ Page Language="C#" MasterPageFile="~/Base.Master" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="Sandbox.Web.Test" %>  
 <%@ MasterType VirtualPath="~/Base.master" %>  

Test.aspx.cs
     private void Page_PreInit(object sender, System.EventArgs e)  
     {  
       // do not index
       Master.DoNotIndex = false;  
     }  

The MasterType declaration provides a way to create a strongly typed reference to the ASP.NET master page when the master page is accessed from the Master property. That allows us to just say Master.DoNotIndex to get/set the publicly exposed property.

Like I said, this example is as simple as it gets, but it allows you to make your master page more generic and only expose the pieces you need from page to page.

Lastly, the reason I prefer an approach like this for the "robots" tag is because it allows me to standardize on a single tag throughout the entire web application to indicate whether or not the page is crawlable or not. An alternative would be to use an asp:ContentPlaceHolder in your master page, and then set the content for it from page to page as needed. I'm not opposed to that solution, and in fact I use that approach quite often for various things, but it really depends on what you are trying to expose and how generic you are trying to keep it. In this case I wanted a single uniform "robots" tag to be defined to not allow a page to be indexed, and if that "robots" tag ever needed to change, I could do that in one place, opposed to each individual content page that had defined it separately.

ASP.NET C# Using Request.Url and Request.ApplicationPath to get your web application's Base Url

If you ever need to get the base domain and application path of your web application, here is a BasePage property that I use regularly.

Code:
     public string BaseUrl  
     {  
       get  
       {  
         // variables  
         string Authority = Request.Url.GetLeftPart(UriPartial.Authority).TrimStart('/').TrimEnd('/');  
         string ApplicationPath = Request.ApplicationPath.TrimStart('/').TrimEnd('/');  
   
         // add trailing slashes if necessary  
         if (Authority.Length > 0)  
         {  
           Authority += "/";  
         }  
   
         if (ApplicationPath.Length > 0)  
         {  
           ApplicationPath += "/";  
         }  
   
         // return  
         return string.Format("{0}{1}", Authority, ApplicationPath);  
       }  
     }  

I like this technique because whether you are using a virtual directory or not, and whether you are using http or https, you can get the base url easily if you need to build a fully-qualified-url withing your application (e.g. sharing a link, sending an email with a link back, etc).

Example output for a top-level site:
http://dev.sandbox.com/

Example output for a virtual directory:
http://dev.sandbox.com/qa/

sys.dm_exec_describe_first_result_set: Getting a Stored Procedure's Result Metadata

If you ever need to work out, at runtime, what columns a stored procedure is going to return, SQL Server has a dynamic management function for exactly that.

Available in SQL Server 2012 and later.

SELECT *
FROM   sys.dm_exec_describe_first_result_set('StoredProcedureName', NULL, 1)

It takes a Transact-SQL statement as a parameter and describes the metadata of the first result set that statement would produce, without executing it.

That is genuinely useful when you are building something generic. If all you need is the column name and data type of each column in the result set:

SELECT 'Property' = name,
       'SqlType'  = system_type_name
FROM   sys.dm_exec_describe_first_result_set('StoredProcedureName', NULL, 1)

Two related objects worth knowing about: sys.dm_exec_describe_first_result_set_for_object takes an object id instead of a statement, and sp_describe_first_result_set does the same job as a stored procedure rather than a function.

For the full syntax, arguments, and the complete list of columns it returns, see the Microsoft documentation.