Blog

Blogging on programming and life in general.

Google Seems To Have An Issue With My Server Response Time...

Posted in: General Development

...and I think I know why...

Out of all the issues Google PageSpeed Insights seems to have when analysing my site, there are two specific things crop up that annoy me:

  1. ‚ÄčReduce server response time
  2. ‚ÄčLeverage browser caching (due to Google Analytics JavaScript file)

The Google Analytics issue is something I will have to live with since (as far as I'm aware) there's nothing I can do. It would be nice if Google wouldn't penalise you for using a product they have developed. However, the "Reduce server response time" was something that perplexed me. My site is relatively simple and not doing anything over-the-top.

Due to the nature of my hosting setup (shared), I didn't have all the capabilities to make my website respond any better. The only way I could think of improving server response time was to move my hosting to another region and purchasing a VPS to get more control.

Now, I think I have resolved the server response time issue...It has something to do with a Web Statistics service called AWStats that was enabled by default as an "addon" service on my hosting. Once disabled through my Plesk Management Portal, Google PageSpeed didn't seem to have any issue with my server response.

I cannot 100% confirm if by disabling the Web Statistics service is a permanent solution and will work for everyone else. But there might be some truth behind this. Web Statistic services like AWStats store all analytical data in log files directly on the server, so this must have some affect on the time a request is made. I could be talking complete nonesense.

If you have experienced the same problem as me, check your own hosting setup and it's "addon" services. You never know, it may give you that extra Google PageSpeed point. :-)

My Paypal REST API .NET Starter Kit

Posted in: ASP.NET

I've just completed working on a site that required PayPal integration to carry out credit card payments, using PayPal's REST API interface. I did find some aspects of the implementing PayPal's REST API a little confusing and there seemed to be a blurred line on what is the best approach. This is probably due to the vast number of .NET examples provided in PayPal's own Github repository.

I decided to create my own PayPal REST API .NET Starter kit, by combining my own efforts together with PayPal documentation and code examples from other developers online. Feel free to fork it from my Bitbucket repository: https://bitbucket.org/SurinderBhomra/paypal-.net-starter-kit.

The PayPal REST API .NET Starter kit contains everything you need to make a start in making your first card payment. It encompasses a very basic form to enter test transactions, as well as the following Nuget package references:

  • log4net
  • Newtonsoft.Json
  • PayPalCoreSDK
  • RestApiSDK

All you'll need to do is create is a PayPal Client ID and Secret, build the solution and away you go. Every time you make a transaction, a "PaypalPayment" object is returned, containing useful information to be used at application level if the payment was a success and if not, the full error information.

A successful transaction will generate the following invoice to the user's PayPal account:

PayPal Invoice Sample

I am using my PayPal Starter kit as a foundation to build upon if I ever get the opportunity to develop more features, such as refunds.

Feel free to modify my code and (even better!) add more features.

Web.Config/App.Config Maintainability

Posted in: ASP.NET, C#

Web Configuration Snippet When working on large projects whether it be websites or software applications, I like to try and make sure that settings from within my app/web configuration files are not only easily accessible within code, but also maintainable for future updates.

Over the years, I have tried different approaches in an attempt to streamline how I use ASP.NET's configuration files within my day-to-day development and this is what I currently do.

Group and Alphabetise

I have started to sort all my settings alphabetically and group common functions/settings together. This alone makes navigating through a large configuration file much more easier.

In addition, having a standard in-house development style and agreeing with your fellow developers how sections within the configuration file is expected to be structured can be useful. For example, on web projects I've worked on, all key sections are  sorted in the following order:

  1. configSections
  2. appSettings
  3. connectionStrings
  4. system.web
  5. customErrors
  6. system.webServer
  7. locations

Common Naming Conventions

I like to name my appsettings in the following format: "<Setting-Group>.<Name>". So if I were to add appsettings that related to Twitter, it would look something as the following:

<add key="Twitter.ApiUrl" value="https://api.twitter.com/1.1/statuses/show.json" />
<add key="Twitter.ApiKey" value="" />
<add key="Twitter.ApiSecret" value="" />
<add key="Twitter.AccessToken" value="" />
<add key="Twitter.AccessTokenSecret" value="" />
<add key="Twitter.Username" value="shomra" />

This provides a simple and descriptive approach to breaking down all settings into manageable chunks.

Strongly-Type AppSettings

One thing that truly annoyed me when I first started .NET development is calling configuration values from within C# code. Not only did you have to write out (the very long-winded!) "ConfigurationManager.AppSettings["Twitter.Username"]", but also cast the value to a specific type.

Using the "ConfigurationManager.AppSettings[]" call is awful. It creates the potential for typo's that aren't caught by the compiler and there's no nice intellisense to make our coding easier.

I create a static configuration wrapper class to strongly-type all my config settings. The way I name my settings (as you can see from the "Common Naming Conventions" section) compliments the structure of my wrapper class.

public class Config
{
    public static class Social
    {
        #region Twitter

        public static class Twitter
        {
            public static string TwitterApiUrl
            {
                get
                {
                    return ConfigurationManager.AppSettings["Twitter.ApiUrl"];
                }
            }

            public static string TwitterUsername
            {
                get
                {
                    return ConfigurationManager.AppSettings["Twitter.Username"];
                }
            }

            public static string TwitterApiKey
            {
                get
                {
                    return ConfigurationManager.AppSettings["Twitter.ApiKey"];
                }
            }

            public static string TwitterApiSecret
            {
                get
                {
                    return ConfigurationManager.AppSettings["Twitter.ApiSecret"];
                }
            }

            public static string TwitterAccessToken
            {
                get
                {
                    return ConfigurationManager.AppSettings["Twitter.AccessToken"];
                }
            }

            public static string TwitterAccessTokenSecret
            {
                get
                {
                    return ConfigurationManager.AppSettings["Twitter.AccessTokenSecret"];
                }
            }
        }

        #endregion
    }
}

Admittingly, this can be quite time-consuming but when compared to the long-term benefits this has saved me a lot of headache.

What Else Could Be Done?

I've seen some developers use Applications Settings Architecture within the .NET framework when building Windows applications by creating a "Settings" file within the project.

The only downside I can see with this approach is that all config values declared within the "Settings" file will be compiled at runtime and you lose the flexibility to change configuration values externally. Here's a nice StackOverflow post that describes this method in greater detail.

If any of you readers have further suggestions or advice, I am all ears! :-)

The Future...

As Nick Dyer quite rightly pointed out to me yesterday on Google+, that our beloved web.config file will no longer form part of the applications we create in ASP.NET 5. We will have the freedom to create an applications configuration the way we want, simplifying the whole process.

As I understand, there will be support for creating configuration inputs that can be placed inside JSON, XML and INI files using the new IConfiguration and ConfigurationModel sources.

Sounds very promising.

Error - Platform type SqlAzureDatabaseSchemaProvider does not support schema file version '2.5'

Posted in: Databases & SQL

Whilst trying to import a .bacpac database exported from an SQL Azure platform onto Microsoft SQL Server 2012, I received the following error:

Internal Error. The internal target platform type SqlAzureDatabaseSchemaProvider does not support schema file version '2.5'. (File: C:\Users\Surinder\Downloads\SurinderAzureDB.bacpac) (Microsoft.Data.Tools.Schema.Sql)

Now it seems many people online have been encountering this horrible error and majority of my fellow bloggers have suggested that installing the SQL Server Data Tools – December 2012 Update for VS 2010 or 2012 will resolve this issue. Unfortunately installing this alone did not help me. I found out that I missed one key part of my SQL Server installation: Service Pack 2!

Can't believe this one small oversight caused me such a headache.

You can download Microsoft SQL Server 2012 SP2 from the following link: https://www.microsoft.com/en-gb/download/details.aspx?id=43340.

Extension Method To Render Action As String

Posted in: ASP.NET

A while ago, I wrote a post that showed how you would Render a Partial View As A String. But what if you had a Partial View and wanted to output its action to a string?

Just like the majority of all other coding problems I encounter, StackOverflow always has the answer. In this case, a clever guy posted this piece of code:

var sw = new StringWriter();
PartialViewResult result = Email("Subject", "Body");

result.View = ViewEngines.Engines.FindPartialView(ControllerContext, "Email").View;

ViewContext vc = new ViewContext(ControllerContext, result.View, result.ViewData, result.TempData, sw);

result.View.Render(vc, sw);

var html = sw.GetStringBuilder().ToString();

Works well enough. However, I didn't like the thought of having to add all this code inside my controller, especially when I have to output many Partial View actions to a string. So I created an extension method:

/// <summary>
/// Renders a Partial View Action to string.
/// </summary>
/// <param name="controller">Controller to extend</param>
/// <param name="partialView">PartialView to render</param>
/// <param name="partialViewName">Name of Partial View</param>
/// <returns>Renders Partial View as a string</returns>
public static string RenderActionToString(this Controller controller, PartialViewResult partialView, string partialViewName)
{
    using (var sw = new StringWriter())
    {
        partialView.View = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName).View;

        ViewContext vc = new ViewContext(controller.ControllerContext, partialView.View, partialView.ViewData,
            partialView.TempData, sw);

        partialView.View.Render(vc, sw);

        return sw.GetStringBuilder().ToString();
    }
}

This extension method can be used in the following way:

//Access PollController class.
PollController pc = new PollController();

//Get the LatestPoll PartialView action and output to string.
string myPartialView = this.RenderActionToString(pc.LatestPoll(), "../Poll/_LatestPoll");

Much cleaner!

 

TextMode Causes Max Length To Not Work In ASP.NET Web Forms

Posted in: ASP.NET

After quite a successful stint in creating some really amazing websites using MVC Razor 5, I had to revert back to working in the world of Web Forms for a new client project. Now I have to deal with .NET web controls, Postbacks and Viewstates.

When creating a few simple forms consisting of some drop down lists, textboxes and textareas, I noticed wherever I set a "MaxLength" property it would not work. A character limit on my input field would just be ignored in all browsers. I could only replicate this bug when the Max Length property is used alongside the "TextMode" property.

There were various places where I had the "TextMode" property set to either "Number" or "MultiLine". Soon as this was removed, the value set in "MaxLength" would work.

How very odd...

Thankfully, I am not the only person to experience the same issue. Currently, the only way to get around this problem is to add the following JavaScript code (slightly refactored for my own implementation) to check the character length "onKeyDown".

var ASPNETForm = {
    "CheckTextAreaLength": function(textBox, e, length) {
        var mLen = textBox["MaxLength"];

        if (null == mLen)
            mLen = length;

        var maxLength = parseInt(mLen);
        if (!ASPNETForm.CheckSpecialKeys(e)) {
            if (textBox.value.length > maxLength - 1) {
                if (window.event) { //IE
                    e.returnValue = false;
                    return false;
                }
                else //Firefox
                    e.preventDefault();
            }
        }
    },
    "CheckSpecialKeys": function(e) {
        if (e.keyCode != 8 && e.keyCode != 46 && e.keyCode != 35 && e.keyCode != 36 && e.keyCode != 37 && e.keyCode != 38 && e.keyCode != 39 && e.keyCode != 40)
            return false;
        else
            return true;
    }
}

Add to your ASP.NET TextBox control as so:

<asp:textbox id="Instructions" MaxLength="50" onkeydown="return ASPNETForm.CheckTextAreaLength(this,event,'50');" runat="server" textmode="MultiLine">
</asp:textbox>

I am hoping there will be a more elegant solution in ASP.NET 5, or even better, a fix. This problem has been lurking around since 2009!

Change Colour of Address Bar In Chrome For Android

Posted in: Client-side

My Nexus 5 upgraded to Android version 5.0 a few months back and it's by far the best update yet (apart from the minor bugs). An OS that is as beautiful to look at as well as use.

One of the most intriguing things I noticed was that the colour of my Chrome browser address bar would occasionally change if I went certain websites. Being a developer who works in the web industry, this peaked my interest. So I had to find out how to do this.

After doing some online research, I found adding the this feature couldn't be simpler. Just add the following META tag to your page:

<meta name="theme-color" content="#4c7a9f">

I carried out this change on my site and it looks kinda cool!

Before

Android Chrome Browser Colour (Before)

After

Android Chrome Browser Colour (After)

Redirect Non-WWW to WWW Domain In Azure Websites

Posted in: Azure

If you require your website URL to always be prefixed with a "www" at the start of the domain, then you will need to modify the web.config (preferably in the Web.Release.Config) with the following addition:

<system.webServer>
    <rewrite xdt:Transform="Insert">
      <rules>
        <rule name="Redirect to WWW site">
          <match url=".*" />
          <conditions logicalGrouping="MatchAny">
            <add input="{HTTP_HOST}" pattern="^(www\.)(.*)$" negate="true" />
          </conditions>
          <action type="Redirect" url="http://www.HTTP_HOST}/{R:0}" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

In addition to the web.config file changes, ensure the Azure Website instance contains the correct domain bindings within the "Manage Domains" area. For example:

Azure Manage Custom Domains

Detecting Facebook In-App Browser

It seems there is going to be a growing trend where apps on our mobile devices will open webpages whilst you are inside the app itself instead of using the devices' native browser. A prime example of this is Facebook. In recent updates during the tail end of last year, both their iOS and Android offerings open webpages from within the application.

This isn't a bad thing. In fact I quite like having webpages opening within the application, since this creates a nice seamless experience. However, the Facebook in-app browser doesn't seem to render a webpage in the same manner as the devices' own native browser (Safari/Chrome). I started noticing this whilst working on a complex website that was very much custom JavaScript driven.

The only thing I could do is modify specific mark-up or features that affected my website negatively when opened from within Facebook by detecting the user-agent. In my code (using ASP.NET C#), I was required to carry out additional browser checks:

//User is within Facebook browser.
if (Request.UserAgent.IndexOf("FBAN") > -1)
{
    if (Request.UserAgent.Contains("iPhone OS 8_0_2"))
    {
        //You are using iPhone version 8.0.2.
    }
    
    if (Request.UserAgent.Contains("Chrome"))
    {
        //You are in the Facebook App in Android.
    }
}
else
{
    //You are not in Facebook App.
}

You can modify the code above to create a nice self-contained method to return an enumeration as I ended up doing to be used when required.

Dynamic Robots.txt file for ASP.NET MVC Sites

Posted in: ASP.NET

Changing the contents of a robots.txt file when a site is moved from staging to a live environment is quite a manual and somewhat cumbersome process. I sometimes have the fear of forgetting to replace the "Disallow: /" line with correct indexable entries required for the website.

To give me one less thing to remember during my pre-live deployments, all my current and upcoming ASP.NET MVC sites will use a dynamic robots.txt file containing different entries depending on whether a site is in stage or live. In order to do this, we need to let the ASP.NET MVC application serve up the robots.txt file. This can be done by the following:

  • Create a new controller called "SEOController"
  • Add a new FileContentResult action called "Robots".
  • Add a new route.
  • Modify web.config.

SEOController

I have created a new controller that renders our "Robots" action as a plain text file. As you can see, my controller is not a type of "ActionResult" but a "FileContentResult". The great thing about "FileContentResult" is that it allows us to return bytes from the controller.

In this example, I am converting bytes from a string using Encoding.UTF8.GetBytes() method. Ideal for what we need to generate a robots.txt file.

[Route("robots.txt")]
[Route("Robots.txt")]
public FileContentResult Robots()
{
    StringBuilder robotsEntries = new StringBuilder();
    robotsEntries.AppendLine("User-agent: *");

    //If the website is in debug mode, then set the robots.txt file to not index the site.
    if (System.Web.HttpContext.Current.IsDebuggingEnabled)
    {
        robotsEntries.AppendLine("Disallow: /");
    }
    else
    {
        robotsEntries.AppendLine("Disallow: /Error");
        robotsEntries.AppendLine("Disallow: /resources");
        robotsEntries.AppendLine("Sitemap: http://www.surinderbhomra.com/sitemap.xml");
    }

    return File(Encoding.UTF8.GetBytes(robotsEntries.ToString()), "text/plain");
}

RouteConfig

Since I add my routing at controller level, I add the "MapMvcAttributeRoutes" method to the RouteConfig.cs file. But if you prefer to add your routes directly here, then this method can be removed.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes(); //Add this line!

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Web.config

Add a "runAllManagedModulesForAllRequests" attribute to the modules tag in the web.config file to allow our robot.txt text file to be rendered by ASP.NET.

<system.webserver>
  <modules runallmanagedmodulesforallrequests="true"></modules>
</system.webserver>
;