<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mark Keats</title>
	<atom:link href="http://www.keats.me.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.keats.me.uk</link>
	<description>Software Engineer and UX/IA Pro</description>
	<lastBuildDate>Thu, 27 May 2010 12:10:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Extension Methods for JSON Serialization</title>
		<link>http://www.keats.me.uk/2010/01/extension-methods-for-json-serialization/</link>
		<comments>http://www.keats.me.uk/2010/01/extension-methods-for-json-serialization/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 10:59:27 +0000</pubDate>
		<dc:creator>Mark Keats</dc:creator>
		
		<guid isPermaLink="false">http://www.keats.me.uk/?p=319</guid>
		<description><![CDATA[Here are some quick extension methods that I created to easily serialize to and from JSON strings. public static string ToJson(this object obj) { var ms = new MemoryStream(); var jsonSerializer = new DataContractJsonSerializer(obj.GetType()); jsonSerializer.WriteObject(ms, obj); ms.Position = 0; var sr = new StreamReader(ms); var json = sr.ReadToEnd(); return json; } public static T FromJson&#60;T&#62;(this [...]]]></description>
			<content:encoded><![CDATA[<p>Here are some quick extension methods that I created to easily serialize to and from JSON strings.</p>
<pre class="brush: csharp;">
public static string ToJson(this object obj)
{
	var ms = new MemoryStream();

	var jsonSerializer = new DataContractJsonSerializer(obj.GetType());
	jsonSerializer.WriteObject(ms, obj);

	ms.Position = 0;
	var sr = new StreamReader(ms);
	var json = sr.ReadToEnd();

	return json;
}
</pre>
<pre class="brush: csharp;">
public static T FromJson&lt;T&gt;(this string jsonString) where T:class
{
	var bytes = Encoding.UTF8.GetBytes(jsonString);
	var ms = new MemoryStream(bytes);
	var jsonSerializer = new DataContractJsonSerializer(typeof(T));
	return jsonSerializer.ReadObject(ms) as T;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.keats.me.uk/2010/01/extension-methods-for-json-serialization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving from WCF JSON Services to MVC</title>
		<link>http://www.keats.me.uk/2009/09/moving-from-wcf-json-services-to-mvc/</link>
		<comments>http://www.keats.me.uk/2009/09/moving-from-wcf-json-services-to-mvc/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 20:07:01 +0000</pubDate>
		<dc:creator>Mark Keats</dc:creator>
		
		<guid isPermaLink="false">http://www.keats.me.uk/?p=291</guid>
		<description><![CDATA[Currently I&#8217;m working on porting a WebForms/ WCF ASP.NET application over to the ASP.NET MVC framework. The client-side code is written wholly in jQuery and the server-side code is in WCF .SVC files. For the move I wanted to move the code out of the .SVC files and into actions on the relevant controllers, so [...]]]></description>
			<content:encoded><![CDATA[<p>Currently I&#8217;m working on porting a WebForms/ WCF ASP.NET application over to the ASP.NET MVC framework. The client-side code is written wholly in jQuery and the server-side code is in WCF .SVC files. For the move I wanted to move the code out of the .SVC files and into actions on the relevant controllers, so that it was in a more logical place.</p>
<p>Currently the JavaScript for calling a POST method looks like this (standard jQuery AJAX):</p>
<pre class="brush: jscript;">
$.ajax({
	url: '/MyWcfService.svc/MyMethod',
	type: &quot;POST&quot;,
	dataType: 'json',
	data: JSON.stringify({ Name: 'Test', Enabled: true }),
	contentType: &quot;application/json; charset=utf-8&quot;,
	success: function(result) {
		alert('Result' + result);
	}
});
</pre>
<p><em>[See <a href="http://www.json.org/json2.js">http://www.json.org/json2.js</a> for the JSON2 library]</em></p>
<p>And the server-side code looks like this:</p>
<pre class="brush: csharp;">
[OperationContract]
[WebInvoke(Method = &quot;POST&quot;, BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
bool MyMethod(SomeDto dto)
{
	// Do some work here.
	return true;
}

[DataContract]
public class SomeDto
{
	[DataMember]
	public string Name{ get; set; }

	[DataMember]
	public bool Enabled { get; set; }
}
</pre>
<p>If you simply port over to an MVC action that uses strongly-types objects you&#8217;ll find that the framework doesn&#8217;t de-serialize the JSON object into your object correctly. To make it work in the same way as the WCF solution requires you to create an <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute.aspx">ActionFilterAttribute</a> that intercepts the request and de-serializes the JSON object manually. Here is my filter (created using an example from StackOverflow):</p>
<pre class="brush: csharp;">
public class JsonFilter : ActionFilterAttribute
{
	public string Param { get; set; }
	public Type JsonDataType { get; set; }

	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		if (filterContext.HttpContext.Request.ContentType.Contains(&quot;application/json&quot;))
		{
			var jsonSerializer = new DataContractJsonSerializer(JsonDataType);
			var result = jsonSerializer.ReadObject(filterContext.HttpContext.Request.InputStream);
			filterContext.ActionParameters[Param] = result;
		}
		else
			throw new InvalidOperationException(&quot;Cannot use the JSON filter on this request as the content type is not marked as 'application/json'.&quot;);
	}
}
</pre>
<p>Now you can decorate your action with this attribute and your JSON will be de-serialized into your strongly-typed object exactly as it was in WCF:</p>
<pre class="brush: csharp;">
[HttpPost]
[JsonFilter(Param=&quot;dto&quot;, JsonDataType=typeof(SomeDto))]
public ActionResult MyMethod(SomeDto dto)
{
	// Do some work here.
	return Json(true);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.keats.me.uk/2009/09/moving-from-wcf-json-services-to-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET Testing with Selenium</title>
		<link>http://www.keats.me.uk/2009/06/asp-net-testing-with-selenium/</link>
		<comments>http://www.keats.me.uk/2009/06/asp-net-testing-with-selenium/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 15:37:20 +0000</pubDate>
		<dc:creator>Mark Keats</dc:creator>
		
		<guid isPermaLink="false">http://www.keats.me.uk/?p=210</guid>
		<description><![CDATA[A week ago a colleague sent me a link to Selenium, which is a new web application testing system. Here is a beginners guide to using it to perform ASP.NET web UI testing with NUnit.]]></description>
			<content:encoded><![CDATA[<p>When I started my first job out of university back in 2003 there were very few testing tools for ASP.NET, and the ones that were around didn&#8217;t really work well. Since that time I have seen web application testing systems crop up from time-to-time, but none of them have ever really stood out as working how I&#8217;d like them to.</p>
<p>A week ago a colleague sent me a link to <a href="http://seleniumhq.org/" target="_blank">Selenium</a>, which is a new web application testing system that I have been looking at. It allows you to build tests like you would record macros in Office, then run them from NUnit. Selenium also allows you to run tests on other operating system and browsers, such as Safari on Mac OS X.</p>
<p>Selenium has 3 parts of interest to anyone looking to create ASP.NET tests:</p>
<ul>
<li><strong>Selenium IDE</strong><br />
The selenium IDE is a Firefox plug-in that allows you to record tests, in the same way that you would record a macro in Office, and play it back.</li>
<li><strong>Selenium RC</strong><br />
Selenium remote control is a command line server on your system (or a test system) and allows Selenium tests to be run from outside the IDE – for example in an NUnit test. Selenium RC is a Java app, so it can run on an Apple Mac to provide access to run Safari tests.</li>
<li><strong>Selenium C# Library</strong><br />
A C# library that provides access Selenium for NUnit tests.</li>
</ul>
<h3>Getting Started</h3>
<p>To get started using Selenium you will need to download the Selenium IDE <a href="http://release.openqa.org/selenium-ide/1.0/selenium-ide-1.0.xpi" target="_blank">from here</a>. This is a Firefox plug-in so make sure that you are using Firefox when you visit that link. Once you have installed the plug-in and re-started this part is ready to go.</p>
<p>You will also need Java installed to run Selenium RC. This can be downloaded <a href="http://java.com/en/" target="_blank">from here</a>.</p>
<h3>Building your First Test</h3>
<p><img class="alignright size-full wp-image-262" title="Selenium IDE Record Button" src="http://www.keats.me.uk/wp-content/uploads/2009/06/SeleniumIDERecord.png" alt="Selenium IDE Record Button" width="41" height="49" />Open Firefox and click <span class="formatted">Tools &gt; Selenium IDE</span> to open the IDE window. The IDE will immediately start recording your actions once open, as indicated by the ‘Now Recording’ button in the top right of the IDE being depressed. Selenium will convert all clicks, text inputs, page loads, etc. into a list of commands that can be played back.</p>
<p>Let’s start by writing a simple test. For this post I created a test for changing a user&#8217;s profile first and last name. With the Selenium IDE running and recording my actions I performed the following in my application:</p>
<ol>
<li>Click on ‘My Account’</li>
<li>Change the First and Last Name to Joe Bloggs.</li>
<li>Click ‘Save’</li>
<li>At the top of the application I select the ‘Joe Bloggs’ text that displays the current user&#8217;s name and right-click to select <span class="formatted">Show All Available Commands &gt; assertText //div[@id='actions']/b</span> (where this XPath will return the &lt;b&gt; element containing the current user&#8217;s name).</li>
</ol>
<p>Your IDE window should now look like this:</p>
<p><img class="alignnone size-full wp-image-263" title="Selenium IDE Test" src="http://www.keats.me.uk/wp-content/uploads/2009/06/SeleniumIDETest.png" alt="Selenium IDE Test" width="502" height="631" /></p>
<p>Click the ‘Now Recording’ button in the top right of the IDE to stop it recording any more of your actions. You now have your first test. Clicking  the green play button in the IDE will run the test in the browser. You can use the IDE to insert new commands and edit the existing ones as needed to tweak and refine your test.</p>
<p>Once you are happy that the test works you click on the ‘Source’ tab in the IDE and then select <span class="formatted">Options &gt; Format &gt; C#</span> from the menu. The IDE will now produce the C# NUnit test for you automatically.</p>
<h3>Creating the NUnit Test</h3>
<p>To use this Selenium test in an NUnit test there are a few things you can do to make things simpler, especially if you need to perform a login before you can run your tests. You can include the SetUp and TearDown methods in each of your test classes, but I created a base test class that has these methods in it. In the set-up method I perform the login actions so that any test I write will automatically be working in a logged-in environment.</p>
<pre class="brush: csharp;">
public class TestBase
{
protected ISelenium selenium;
protected StringBuilder verificationErrors;

[SetUp]
public void SetupTest()
{
selenium = new DefaultSelenium(&quot;localhost&quot;, 4444, &quot;*chrome&quot;, &quot;http://localhost/&quot;);
selenium.Start();
verificationErrors = new StringBuilder();
Login();
}

[TearDown]
public void TeardownTest()
{
try
{
selenium.Stop();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.IsTrue(verificationErrors.ToString() == string.Empty);
}

/// &lt;summary&gt;
/// Performs a login to the application.
/// &lt;/summary&gt;
public void Login()
{
selenium.Open(&quot;/Login.aspx&quot;);
selenium.Type(&quot;//input[@testid='Username']&quot;, &quot;Administrator&quot;);
selenium.Type(&quot;//input[@testid='Password']&quot;, &quot;Password&quot;);
selenium.Click(&quot;//a[@testid='Login']&quot;);
selenium.WaitForPageToLoad(&quot;30000&quot;);
}
}
</pre>
<p>I have cleaned-up the test method and also added some code to restore the first/last name to their original values once the test has run. This method is in a test class that descends from my base test class. Here is the result:</p>
<pre class="brush: csharp;">
[TestFixture]
public class ProfileTests : TestBase
{
[Test]
public void ChangeProfileName()
{
selenium.Open(&quot;/Home.aspx&quot;);

// Click on 'My Account'
selenium.Click(&quot;ctl00_HeaderNavigation1_myAccountLink&quot;);
selenium.WaitForPageToLoad(&quot;30000&quot;);

var firstName = selenium.GetValue(&quot;ctl00_ContentPlaceHolder1_ctl00_firstNameTextBox&quot;);
var lastName = selenium.GetValue(&quot;ctl00_ContentPlaceHolder1_ctl00_lastNameTextBox&quot;);

// Enter new first/last name and save.
selenium.Type(&quot;ctl00_ContentPlaceHolder1_ctl00_firstNameTextBox&quot;, &quot;Joe&quot;);
selenium.Type(&quot;ctl00_ContentPlaceHolder1_ctl00_lastNameTextBox&quot;, &quot;Bloggs&quot;);
selenium.Click(&quot;ctl00_ContentPlaceHolder1_ctl00_saveLinkButton&quot;);

// Verify name has changed.
selenium.WaitForPageToLoad(&quot;30000&quot;);
Assert.AreEqual(&quot;Joe Bloggs&quot;, selenium.GetText(&quot;//div[@id='actions']/b&quot;));

// Restore Data
selenium.Click(&quot;ctl00_HeaderNavigation1_myAccountLink&quot;);
selenium.WaitForPageToLoad(&quot;30000&quot;);
selenium.Type(&quot;ctl00_ContentPlaceHolder1_ctl00_firstNameTextBox&quot;, firstName);
selenium.Type(&quot;ctl00_ContentPlaceHolder1_ctl00_lastNameTextBox&quot;, lastName);
selenium.Click(&quot;ctl00_ContentPlaceHolder1_ctl00_saveLinkButton&quot;);
}
}
</pre>
<h3>Running The NUnit Test</h3>
<p>To run the test you first need to start the Selenium RC server on your local system. If you have Java installed all you need to do is run <span class="command">java -jar selenium-server.jar</span>. With the server running you just run the NUnit test in your normal test runner. When the test runs you will see a new instance of Firefox open up and the test will run inside this. The output and result of your test will appear like any other &#8216;normal&#8217; NUnit test in your runner:</p>
<p><img class="alignnone size-full wp-image-264" title="ReSharper Test Runner Success" src="http://www.keats.me.uk/wp-content/uploads/2009/06/ReSharperTestRunnerSuccess.png" alt="ReSharper Test Runner Success" width="685" height="432" /></p>
<h3>Control IDs and Possible Problems</h3>
<p>One thing you will notice is that by default the Selenium IDE creates tests using the ID of a control to identify it. This may be a problem in ASP.NET as the ID of a control when it is rendered can change if the control hierarchy on a page changes for any reason – maybe dynamically added controls or UI design modifications.</p>
<p>To solve this problem I wrote an extension method for WebControl called AssignTestID. This will add a <span class="formatted">testid=”blah”</span> attribute to the HTML control, which we can use to identify it in our tests:</p>
<pre class="brush: csharp;">
public static void AssignTestID(this WebControl ctrl)
{
ctrl.AssignTestID(ctrl.ID);
}

public static void AssignTestID(this WebControl ctrl, string testId)
{
ctrl.Attributes.Add(&quot;TestID&quot;, testId);
}
</pre>
<p>Then update our NUnit test with:</p>
<pre class="brush: csharp;">
selenium.Type(&quot;//input[@testid='FirstName']&quot;, &quot;Joe&quot;);
selenium.Type(&quot;//input[@testid='LastName']&quot;, &quot;Bloggs&quot;);
selenium.Click(&quot;//a[@testid='Save']&quot;);
</pre>
<p>You can also use any other XPath to select an element, but it really depends on your page layouts as to what would be suitable for your application . A good tutorial on XPath can be <a href="http://www.zvon.org/xxl/XPathTutorial/General/examples.html" target="_blank">found here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keats.me.uk/2009/06/asp-net-testing-with-selenium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wildcard SSL Certificates in IIS7 with Host Headers</title>
		<link>http://www.keats.me.uk/2009/06/wildcard-ssl-certificates-in-iis7-with-host-headers/</link>
		<comments>http://www.keats.me.uk/2009/06/wildcard-ssl-certificates-in-iis7-with-host-headers/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 08:12:35 +0000</pubDate>
		<dc:creator>Mark Keats</dc:creator>
		
		<guid isPermaLink="false">http://www.keats.me.uk/?p=213</guid>
		<description><![CDATA[I have just run into an interesting issue with IIS7 when using the HTTPS protocol to secure a site. It happens that when you use HTTPS you are unable to use host headers. Luckily there is a workaround if you want to use a wildcard SSL certificate.]]></description>
			<content:encoded><![CDATA[<p>I have just run into an interesting issue with IIS7 when using the HTTPS protocol to secure a site. At work we have a Salesforce integration that loads our ASP.NET application inside an IFrame, but because Salesforce is secured over HTTPS and our application isn&#8217;t users were receiving a &#8221;This page contains non-secure content&#8230;&#8217; error message when using their Salesforce application.</p>
<p>All our client system are available as sub-domains under our company&#8217;s main domain i.e. client1.domain.com, client2.domain.com, etc. To provide us with flexibility and the most cost effective solution I purchased a wildcard SSL certificate from GoDaddy, which would secure *.domain.com; allowing us to use a single SSL certificate for all our clients.</p>
<p>Installing the SSL certificate in IIS is fairly straigh forward, and is covered in detail on the GoDaddy support site. The problem starts when you try to add a binding to a site using HTTPS. As shown in the screenshot below you will see that when you choose the HTTPS protocol the host name box is disabled:</p>
<p><img class="size-full wp-image-218 alignnone" title="Host Header Greyed Out for HTTPS" src="http://www.keats.me.uk/wp-content/uploads/2009/06/host-header-greyed-out.png" alt="Host Header Greyed Out for HTTPS" width="483" height="261" /></p>
<p>Researching this brings up the reasoning behind it, as detailed in a <a href="http://blogs.iis.net/thomad/archive/2008/01/25/ssl-certificates-on-sites-with-host-headers.aspx" target="_blank">post on Thomas Deml&#8217;s blog</a>:</p>
<blockquote><p>The host name is encrypted in the SSL blob that the client sends. Because the host name is part of the binding IIS needs the host name to lookup the right certificate. Without the host name IIS can&#8217;t lookup the right site because the binding is incomplete. Without the certificate IIS can&#8217;t decrypt the SSL blob that contains the host name.</p></blockquote>
<p>Luckily there is a way to get round this, but it will only work if all the sites you want to secure in IIS are covered by a single SSL certificate. As all our sites would be secured with just our one wildcard certificate I was able to use <a href="http://www.sslshopper.com/article-ssl-host-headers-in-iis-7.html" target="_blank">this method</a>.</p>
<p>First you must set-up the Default Web Site on your server (i.e. the site that has no host header specified) to have a HTTPS binding. This HTTPS binding must be configured to use your wildcard SSL certificate, as any bindings with host names we add later to other sites will use the certificate selected here.</p>
<p><img class="alignnone size-full wp-image-223" title="Default Web Site HTTPS Binding" src="http://www.keats.me.uk/wp-content/uploads/2009/06/default-site-https-binding.png" alt="Default Web Site HTTPS Binding" width="558" height="231" /></p>
<p>Once you have this configured you then need to run the following command (found in C:\Windows\System32\Inetsrv\) for each site you want to secure:</p>
<p><code>appcmd set site /site.name:"&lt;SiteName&gt;" /+bindings.[protocol='https',bindingInformation='*:443:&lt;HostHeader&gt;']</code></p>
<p>Return to IIS and you will now see that your sites have a HTTPS binding with a host header and the SSL certificate that was specified for your Default Web Site is selected:</p>
<p><img class="alignnone size-full wp-image-220" title="HTTPS Binding with Host Header" src="http://www.keats.me.uk/wp-content/uploads/2009/06/site-https-binding-with-host-header.png" alt="HTTPS Binding with Host Header" width="483" height="261" /></p>
<p>One last point to make here is that if you try to edit this binding IIS will delete the host header and change the SSL certificate back to &#8216;Not Selected&#8217;. If this happens you will need to delete the binding and re-run the command line to add it again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.keats.me.uk/2009/06/wildcard-ssl-certificates-in-iis7-with-host-headers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
