Consuming RSS Feeds in C#

I have never consumed an RSS feed in code before and assumed it would be a bespoke process, but the System.ServiceModel.Syndication library has a everything you need in a few lines of code;

 string url = "http://blog.jongregory.net/syndication.axd";
            XmlReader reader = XmlReader.Create(url);
            SyndicationFeed feed = SyndicationFeed.Load(reader);
            reader.Close();
            foreach (SyndicationItem item in feed.Items)
            {
                Console.WriteLine("Title {0}",item.Title.Text);
                var summary = HttpUtility.UrlDecode(item.Summary.Text);
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Summary {0}", summary);
             }
               

 Quick and simple can also be used to create RSS feeds.

Testing Web Config IP Restrictions Locally

I was up against a hard deadline recently and needed to test some IP restrictions locally before deploying to a dev server. I have never had to do this locally before and had to jump through a few hoops to get it working. 

We wanted to put the restrictions in the config so they are applied to any environment the site is hosted on, this is easily achieved using the <ipSecurity> attribute in the <security> group. 

The sample xml below shows a configuration where all IP's are blocked except the ones listed, it is possible to invert this with the allowUnlisted attribute being set to true. When this is the case the IP's in the list are not allowed to access the site.

    <security>
      <ipSecurity allowUnlisted="false" denyAction="Forbidden">
        <!-- this line blocks everybody, except those listed below -->
        <!-- removes all upstream restrictions -->
        <clear/>
        <!-- allow requests from the local machine -->
        <add ipAddress="127.0.0.1" allowed="true"/>
        <!-- Allowed IP's-->
        <add allowed="true" ipAddress="0.0.0.0" subnetMask="255.255.0.0" />
      </ipSecurity>
    </security>

This iis.net article details the options for IP configuration restriction as well as other options https://www.iis.net/configreference/system.webserver/security/ipsecurity?showTreeNavigation=true#005

To get this working on my local machine I had to do three other steps , although one may not have been required!

 

1 - Turn on the IIS Role service for IP security via the Turn Windows Features On and Off - the steps are detailed here https://www.iis.net/configreference/system.webserver/security/ipsecurity?showTreeNavigation=true#003

2 - Allow the Security section to be overridden at the application level, within IIS the Security section is locked for override and needs to be set to Read/Write in the Feature Delegation settings. This is available at the server level in IIS and is covered in this blog post https://www.iis.net/learn/manage/managing-your-configuration-settings/an-overview-of-feature-delegation-in-iis#02

3 - Allow Override in the ApplicationHost.config files, there are two of these one for the machine located at %windir%\system32\inetsrv\config\applicationHost.config and another in the project folder at .vs\config. I set both to be safe but it maybe that only the project level one is required.

This is an example of the required setting 

<section name="ipSecurity" overrideModeDefault="Allow" />

This is the stack overflow post that pointed me in the right direction for the ApplicationHost.config http://stackoverflow.com/questions/16220819/internal-server-error-with-web-config-ipsecurity

 

 

Consistent Redirects and Session State

One thing I learnt from experience to check when getting unexpected behaviour with sessions in ASP.Net is the redirects. I have worked on sites where the HTTP and HTTPS redirects are inconsistent and this can cause issues.
 
One of the more serious cases experiences was were a 'www' redirect was missing and redirect was being used to transfer to a third party site. In this case the user started a session using the address at http://websitedomain... and then transferred to the third party site.
 
When the user was redirected to the full web address http://www.websitedomain... a new session was started by IIS and the user lost their session and all information associated with it. This severely affected the user experience on the site.
 
Many issues with lost sessions are difficult to diagnose due to the symptoms being misleading. Fortunately the fix is quick and easy , simply specifying the redirects in the web.config for the site ensured the consistency of URL for all sessions on the site.
 
These rules can be put into IIS but these can be lost in some cases when the web.config is overwritten on a deployment. In the rules are in the web.config then there is the benefit of versioning in source control and consistency across web-farms.
 
 

Here is an example web.config entry for http to https and non-www to www redirects;

   <rewrite>
      <rules>
        <rule name="Redirect landing request to trailing slash" stopProcessing="true">
          <match url="landing\/(.*[^\/])$" />
          <action type="Redirect" url="{R:0}/" redirectType="Permanent" />
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" />
          </conditions>
        </rule>
        <rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{HTTPS}" pattern="^OFF$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:0}" redirectType="Permanent" />
        </rule>
        <rule name="redirect non www to www" stopProcessing="true">
          <match url=".*" />
          <conditions  logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{HTTP_HOST}" pattern="^domain.com$" />
          </conditions>
          <action type="Redirect" url="https://www.domain.com/{R:0}" />
        </rule>
      </rules>
    </rewrite>

C# Importance of Checking for NULLs

This week I was reviewing some C# code where the developer had used 'ToString()' throughout on properties without checking for nulls. 

 
The result of this was a log file full of 'System.NullReferenceException: Object reference not set to an instance of an object.'
 
And it was difficult to trace through where the error had occurred and the logic stopped executing.
 
So I put together a few simple samples of how to safely check for nulls and work with collections,  I can distribute them to the training developers and add hope to add more to this project over time. The code is  available here;
 
 
Some of the samples are below.
 
Examples Ways to handle null values
 
AS Operator
 
//https://msdn.microsoft.com/en-us/library/cscsdfbt.aspx

var asOperator = classWithNulls.IamNull as string;
Console.WriteLine("Null is returned by as with no exception : " + asOperator);
 
Convert Class
 
// https://msdn.microsoft.com/en-us/library/system.convert(v=vs.110).aspx

var convertToString = Convert.ToString(classWithNulls.IamNull);
Console.WriteLine("Convert Class returns empty string if null no exception : " + convertToString);
 
Coalesce Operator
 
//https://msdn.microsoft.com/en-GB/library/ms173224.aspx

var coalesce = classWithNulls.IamNull ?? "DefaultValueIfNull";
Console.WriteLine("DefaultValue is returned if null : " + coalesce);
 
Conditional Operator
 
//https://msdn.microsoft.com/en-gb/library/ty67wk28.aspx

// ReSharper disable once MergeConditionalExpression
var conditional = classWithNulls.IamNull != null
    ? classWithNulls.IamNull.ToString()
    : "DefaultValueIfNull";

Console.WriteLine("DefaultValue is returned if null : " + conditional);

// C# 6 and later null propagation operator where the null value is passed up the chain without an exception
//https://msdn.microsoft.com/en-GB/library/dn986595.aspx

var conditionalCSharp6 = classWithNulls.IamNull?.ToString();

Console.WriteLine("Null is propagated and returned without an Exception" + conditionalCSharp6);

// This can be combined with Coalesce to remove the null and provide a default value
var conditionalCSharp6DefaultValue = classWithNulls.IamNull?.ToString() ?? "DefaultValueIfNull";
Console.WriteLine("Default Value Returned without an Exception" + conditionalCSharp6DefaultValue);
 
Extension Method
 
 
public static class Extension
    {
        public static string ToStringOrEmpty(this Object value)
        {
            return value == null ? "" : value.ToString();
        }
    }


// A custom extension method attached to object to handle null values, see file ToStringOrEmpty.cs
// https://msdn.microsoft.com/en-gb/library/bb383977.aspx

var extensionMethod = classWithNulls.IamNull.ToStringOrEmpty();
Console.WriteLine("String Empty is returned by as with no exception : " + extensionMethod);
 
 
 

SSL V 3.0 - Disable Poodle Threats on IIS


On a recent PEN test the SSL V3 POODLE bug was picked up on the server http://www.symantec.com/connect/blogs/ssl-30-vulnerability-poodle-bug-aka-poodlebleed

To test a website this handy page reports on any url visible to the browser https://cryptoreport.thawte.com/checker/views/certCheck.jsp

I assumed this would be a setting in IIS but the advice from Microsoft is a quick registry edit - detailed in the ''Disable SSL 3.0 Server Software'' section in this article https://technet.microsoft.com/library/security/3009008.aspx

Disable SSL 3.0 in Windows For Server Software

You can disable support for the SSL 3.0 protocol on Windows by following these steps:

  1. Click Start, click Run, type regedt32 or type regedit, and then click OK.
  2. In Registry Editor, locate the following registry key:
    HKey_Local_Machine\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server
    

    Note If the complete registry key path does not exist, you can create it by expanding the available keys and using the New -> Key option from the Edit menu.

  3. On the Edit menu, click Add Value.
  4. In the Data Type list, click DWORD.
  5. In the Value Name box, type Enabled, and then click OK

    Note If this value is present, double-click the value to edit its current value.

  6. In the Edit DWORD (32-bit) Value dialog box, type 0 .
  7. Click OK. Restart the computer.

 

Note This workaround will disable SSL 3.0 for all server software installed on a system, including IIS.









ASP.NET Web Forms - Intermittent View State Error


On a web forms application on load balanced environment I recently had to investigate some errors for invalid viewstate. It was an intermittent error which only occurred when someone important used the site.

This became high profile quickly and very annoying, it has been a long time since I had to deal with view state thanks to MVC and it was difficult to reproduce. Eventually we found that clearing all caches and browser history allowed the error to be recreated.

The error message was a value cannot be null error;

System.Web.HttpException: Value cannot be null.
Parameter name: inputString [ArgumentNullException: Value cannot be null.Parameter name: inputString]
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString, Purpose purpose)
at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter2 formatter, String serializedState, Purpose purpose)
at System.Web.UI.HiddenFieldPageStatePersister.Load()
[ViewStateException: Invalid viewstate. Client IP: 86.131.46.52 Port: 49531 Referer: https://*********.com/checkout/payment Path: *******.aspx User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko ViewState: ] [HttpException: The state information is invalid for this page and might be corrupted.]

The machinekey was in the web.config for both servers and the load balancing set up correctly. Looking at New Relic there was more viewstate errors which didn''t hit the application so were not logged.

The most likely solution found when googling was to move the machine key to the machine.config file at the server level C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config

The site web.config had the machine key removed and there is a web.config in the same directory as the machine.config , in one server this had the machine key and on another it didn''t. So it was removed from all.

This url has some useful information about the scope of the configuration files


ASP.NET 4.5 introduced cryptographic improvements, when the configuration was set wrong these were picked up and the following error was received.

System.Configuration.ConfigurationErrorsException: When using <machineKey compatibilityMode="Framework45" /> or the MachineKey.Protect and MachineKey.Unprotect APIs, the ''validation'' attribute must be one of these values: SHA1, HMACSHA256, HMACSHA384, HMACSHA512, or alg:[KeyedHashAlgorithm]. (C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config line 31)

Explicitly setting the validation key'' validation="SHA1" '' to ensure the correct encryption  setting  was picked up solved this.

There is more information about the improvements here;


But after all that reconfiguration  the error popped up once more in New Relic!

After some more investigation we found that the viewstate had been moved to the bottom of the page for SEO, on the page receiving the error it was possible to submit the page before it had completed loading and then error then occured. Moving the viewstate back to the top seems to have cured it but we are keeping a close eye on New Relic

Sql Server Management Studio Results to Excel

I need to do some quick analysis on a error log table, so was running a grouping query on the log table.

To get the results into excel I wanted to cut and paste the results from SSMS query window into excel.

Annoyingly the .Net Exceptions where going into Excel on new rows which made it unreadable. 


With SQL 2012 the line feeds and carriage returns are preseved  and needed to be filtered out in the query

SELECT COUNT(*) as count, replace(replace(Message, char(10), ''''), char(13), '''') as ''Message'' FROM Log

Session State being lost in Web Farm

Investigating and issue with session data being lost on a load balance ASP.Net website the other day, users we''re losing items from a basket when bouncing between servers.

These issues have always been difficult to investigate but it turned out that when setting up the web servers there was multiple sites in IIS. These has been created in different order so had ended up with different site ids. A simple error but the symptoms were dramatic for users and difficult to recreate and trace.

This article details the issues https://support.microsoft.com/en-us/kb/325056 , although I did not have to use the described resolution.

I found that I could just change the site id through IIS, if a another site had the required id I renamed that until both web servers were is sync.

In IIS select the site and advanced settings; the edit the id to the required value




Sql Server Management Studio Freezing On Start Up

For a few weeks I had a really annoying issue with Sql Server Management Studio freezing on start up, this happened a few times at crucial moments and caused me delays.

I tried several re-installs and repairs and even the 2016 RC version, but it would just keep happening randomly.

Until I found his blog and following the second option to clear the profile information.


An bingo it never happened again, turns out the profile data is not removed on a uninstall.