<?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:rssdatehelper="urn:rssdatehelper"><channel><title>TRsDomain.dk Blog</title><link>http://www.trsdomain.dk/</link><pubDate></pubDate><generator>umbraco</generator><description>This is the blog of the Danish developer Torben Warberg Rohde.</description><language>en</language><item><title>SimpleText.NET released</title><link>http://www.trsdomain.dk//blog/2011/5/13/simpletextnet-released.aspx</link><pubDate>Fri, 13 May 2011 15:27:28 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2011/5/13/simpletextnet-released.aspx</guid><content:encoded><![CDATA[ <p>I recently relased the <a target="_blank" title="Read more about SimpleText.NET" href="http://simpletext.codeplex.com/">language versioning SimpleText.NET</a> system/utility on CodePlex.<br />Here the short snip from the project site description:</p>
<p class="simpleblockquote">SimpleText aims at enabling .NET developers to language version sites or apps in a simple manner.<br />A focal point is servicing external translators with MS Excel export/import. <br />Texts can be harvested from your source code based on a simple custom format.</p>
<p><a target="_blank" title="More on CodePlex" href="http://simpletext.codeplex.com/">Read on at the CodePlex site and take it for a spin</a>. Don't hesitate to drop me a line on mail or the CodePlex discussions if you have comments or suggestions for improvents.</p>
<p><img src="/media/6216/simpletext_webadmin_449x298.jpg"  width="449"  height="298" alt="SimpleText_admin" class="imageNormal"/></p>]]></content:encoded></item><item><title>English grammar - Factoid</title><link>http://www.trsdomain.dk//blog/2011/1/20/english-grammar---factoid.aspx</link><pubDate>Thu, 20 Jan 2011 16:39:38 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2011/1/20/english-grammar---factoid.aspx</guid><content:encoded><![CDATA[ <p>Classic English grammar question: "Do I use an or a here".<br />What I learned many years ago was that if the word started with a consonant use "a", otherwise "an". Then I <a target="_blank" title="Post on the use of &quot;an or a&quot;" href="http://english.stackexchange.com/questions/8181/does-one-use-a-or-an-before-the-word-x-ray">read this post and found out I have been wrong</a>.</p>
<p>Spoiler: It depends on the pronunciation not the spelling.</p>]]></content:encoded></item><item><title>Shortening file paths - c-sharp function</title><link>http://www.trsdomain.dk//blog/2011/1/9/shortening-file-paths---c-sharp-function.aspx</link><pubDate>Sun, 09 Jan 2011 04:48:14 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2011/1/9/shortening-file-paths---c-sharp-function.aspx</guid><content:encoded><![CDATA[ <p>When listing some file paths for display in a grid, I found that I needed to shorten them, since they can quickly become to large to fit in the relatively small space I had allocated for them. Instead of simply cropping of the beginning or end I wanted to remove some of the middel directories, just like all the standard Windows apps does in e.g. the "Recent files" overview.</p>
<p class="simpleblockquote">Let's try to turn this:<br /><i>c:\websites\acmeinc\myproject\www_myproj\App_Data\somefile.txt</i><br />into this:<br /><i>c:\websites\acmeinc\...\App_Data\somefile.txt<br /></i><i><br /></i></p>
<p>So I went googling, but found no exact matches. This <a target="_blank" href="http://www.codinghorror.com/blog/2006/08/shortening-long-file-paths.html">post on codinghorror.com</a> points to a trimming function which operates directly on the Win-forms canvas (so you never get hold of the shortened string object) and to a function in the Windows API (which means you have to include a reference to a DLL that is not native .NET).</p>
<p>This is my take on a function for this purpose. It is not as thouroughly tested or performant as an official MS-API-method would be, but I think it should suffice for most purposes:</p>
<pre name="code" class="c-sharp">/// &lt;summary&gt;
/// Shortens a file path to the specified length
/// &lt;/summary&gt;
/// &lt;param name="path"&gt;The file path to shorten&lt;/param&gt;
/// &lt;param name="maxLength"&gt;The max length of the output path (including the ellipsis if inserted)&lt;/param&gt;
/// &lt;returns&gt;The path with some of the middle directory paths replaced with an ellipsis (or the entire path if it is already shorter than maxLength)&lt;/returns&gt;
/// &lt;remarks&gt;
/// Shortens the path by removing some of the "middle directories" in the path and inserting an ellipsis. If the filename and root path (drive letter or UNC server name) in itself exceeds the maxLength, the filename will be cut to fit.
/// UNC-paths and relative paths are also supported.
/// The inserted ellipsis is not a true ellipsis char, but a string of three dots.
/// &lt;/remarks&gt;
/// &lt;example&gt;
/// ShortenPath(@"c:\websites\myproject\www_myproj\App_Data\themegafile.txt", 50)
/// Result: "c:\websites\myproject\...\App_Data\themegafile.txt"
/// 
/// ShortenPath(@"c:\websites\myproject\www_myproj\App_Data\theextremelylongfilename_morelength.txt", 30)
/// Result: "c:\...gfilename_morelength.txt"
/// 
/// ShortenPath(@"\\myserver\theshare\myproject\www_myproj\App_Data\theextremelylongfilename_morelength.txt", 30)
/// Result: "\\myserver\...e_morelength.txt"
/// 
/// ShortenPath(@"\\myserver\theshare\myproject\www_myproj\App_Data\themegafile.txt", 50)
/// Result: "\\myserver\theshare\...\App_Data\themegafile.txt"
/// 
/// ShortenPath(@"\\192.168.1.178\theshare\myproject\www_myproj\App_Data\themegafile.txt", 50)
/// Result: "\\192.168.1.178\theshare\...\themegafile.txt"
/// 
/// ShortenPath(@"\theshare\myproject\www_myproj\App_Data\", 30)
/// Result: "\theshare\...\App_Data\"
/// 
/// ShortenPath(@"\theshare\myproject\www_myproj\App_Data\themegafile.txt", 35)
/// Result: "\theshare\...\themegafile.txt"
/// &lt;/example&gt;
public static string ShortenPath(string path, int maxLength)
{
	string ellipsisChars = "...";
	char dirSeperatorChar = Path.DirectorySeparatorChar;
	string directorySeperator = dirSeperatorChar.ToString();

	//simple guards
	if (path.Length &lt;= maxLength)
	{
		return path;
	}
	int ellipsisLength = ellipsisChars.Length;
	if (maxLength &lt;= ellipsisLength)
	{
		return ellipsisChars;
	}


	//alternate between taking a section from the start (firstPart) or the path and the end (lastPart)
	bool isFirstPartsTurn = true; //drive letter has first priority, so start with that and see what else there is room for

	//vars for accumulating the first and last parts of the final shortened path
	string firstPart = "";
	string lastPart = "";
	//keeping track of how many first/last parts have already been added to the shortened path
	int firstPartsUsed = 0;
	int lastPartsUsed = 0;

	string[] pathParts = path.Split(dirSeperatorChar);
	for (int i = 0; i &lt; pathParts.Length; i++)
	{
		if (isFirstPartsTurn)
		{
			string partToAdd = pathParts[firstPartsUsed] + directorySeperator;
			if ((firstPart.Length + lastPart.Length + partToAdd.Length + ellipsisLength) &gt; maxLength)
			{
				break;
			}
			firstPart = firstPart + partToAdd;
			if (partToAdd == directorySeperator)
			{
				//this is most likely the first part of and UNC or relative path 
				//do not switch to lastpart, as these are not "true" directory seperators
				//otherwise "\\myserver\theshare\outproject\www_project\file.txt" becomes "\\...\www_project\file.txt" instead of the intended "\\myserver\...\file.txt")
			}
			else
			{
				isFirstPartsTurn = false;
			}
			firstPartsUsed++;
		}
		else
		{
			int index = pathParts.Length - lastPartsUsed - 1; //-1 because of length vs. zero-based indexing
			string partToAdd = directorySeperator + pathParts[index];
			if ((firstPart.Length + lastPart.Length + partToAdd.Length + ellipsisLength) &gt; maxLength)
			{
				break;
			}
			lastPart = partToAdd + lastPart;
			if (partToAdd == directorySeperator)
			{
				//this is most likely the last part of a relative path (e.g. "\websites\myproject\www_myproj\App_Data\")
				//do not proceed to processing firstPart yet
			}
			else
			{
				isFirstPartsTurn = true;
			}
			lastPartsUsed++;
		}
	}
	
	if (lastPart == "")
	{
		//the filename (and root path) in itself was longer than maxLength, shorten it
		lastPart = pathParts[pathParts.Length - 1];//"pathParts[pathParts.Length -1]" is the equivalent of "Path.GetFileName(pathToShorten)"
		lastPart = lastPart.Substring(lastPart.Length + ellipsisLength + firstPart.Length - maxLength, maxLength - ellipsisLength - firstPart.Length);
	}

	return firstPart + ellipsisChars + lastPart;
}
</pre>
<p> </p>]]></content:encoded></item><item><title>Glat - hvem går først over?</title><link>http://www.trsdomain.dk//blog/2011/1/2/glat---hvem-gaar-foerst-over.aspx</link><pubDate>Sun, 02 Jan 2011 12:53:10 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2011/1/2/glat---hvem-gaar-foerst-over.aspx</guid><content:encoded><![CDATA[ <p><img src="/media/6067/glat_small_499x665.jpg"  width="499"  height="665" alt="Glat - 2010 01" class="imageNormal"/></p>]]></content:encoded></item><item><title>Reading CSV files on 64 bit Windows Server</title><link>http://www.trsdomain.dk//blog/2010/12/7/reading-csv-files-on-64-bit-windows-server.aspx</link><pubDate>Tue, 07 Dec 2010 16:30:02 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2010/12/7/reading-csv-files-on-64-bit-windows-server.aspx</guid><content:encoded><![CDATA[ 
<p>In the olden days I used the Jet-provider with a <a
href="http://msdn.microsoft.com/en-us/library/ms709353%28VS.85%29.aspx"
 target="_blank" title="Description of schema.ini">schema.ini</a>
to read CSV-files.</p>

<p>Yesterday - after having just finished a small console app on
our 32 bit developer box - I deployed it to our 64 bit production
server..... crash.... "provider not found".</p>

<p>After a fair amount of digging I downloaded one the many
homemade CSV readers... Turns out it was written by an American, so
there was no way to specify the charset of the file ;-)</p>

<p>Then I found the <a
href="http://www.microsoft.com/downloads/en/details.aspx?familyid=C06B8369-60DD-4B64-A44B-84B371EDE16D&amp;displaylang=en"
 target="_blank">"Microsoft Access Database Engine 2010
Redistributable"</a> package (read this small note on how to
specify the connection string).<br />
It's a bit bloated just for reading a CSV file, but it installed in
a few minutes, did not require restarting the server, and it works
perfectly.</p>

<p>&nbsp;</p>
]]></content:encoded></item><item><title>Async made simple(r)</title><link>http://www.trsdomain.dk//blog/2010/11/24/async-made-simple(r).aspx</link><pubDate>Wed, 24 Nov 2010 15:35:44 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2010/11/24/async-made-simple(r).aspx</guid><content:encoded><![CDATA[ <p>If you have ever coded asynchronous stuff in .NET, this upcoming .NET feature should get you fairly psyched.... why handle all the plumbing yourself, when you can just use this new feature, as described in <a href="http://channel9.msdn.com/Blogs/Charles/Anders-Hejlsberg-Introducing-Async" title="Video on new async feature by Anders Hejlsberg">the Channel9 video by Anders Hejlsberg</a></p>
<p>There's probably some sort of downside to this, but I couldn't spot it from what I heard in the presentation :-)</p>]]></content:encoded></item><item><title>Captcha with a twist - Are you a human being?</title><link>http://www.trsdomain.dk//blog/2010/10/22/captcha-with-a-twist---are-you-a-human-being.aspx</link><pubDate>Fri, 22 Oct 2010 15:40:15 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2010/10/22/captcha-with-a-twist---are-you-a-human-being.aspx</guid><content:encoded><![CDATA[ 
<p>Most sites have a captcha check on forms where users can
contribute input such as comments or forum posts. However <a
href="http://www.stackoverflow.com/" target="_blank"
title="Stackoverflow">Stackoverflow</a> have added some twists to
this otherwise standard mechanism - one sophisticated and one...
not so sophisticated (but very humorous).</p>

<p><strong>The sophisticated:</strong> By default there is no
captcha - but if they cannot determine whether you are man or
machine when you post your question/answer, they redirect you to
the captcha page.</p>

<p><strong>The humorous:</strong> Instead of just confronting the
user with a standard captcha form, they have added a picture which
must have been a lot of fun shooting, along with the following
refreshingly down-to-earth text:</p>

<blockquote>
<p><strong>Are you a human being?</strong><br />
 We apologize for the confusion, but we can't <em>quite</em> tell
if you're a person or a script.</p>

<p>Please don't take this personally.<br />
 Bots and scripts can be remarkably lifelike these days!</p>

<p>Enter the CAPTCHA displayed below, and we'll be out of your
way.</p>
</blockquote>

<p><a href="/media/5610/stackoverflow_captcha.png" target="_blank"
title="View full resolution version"><img src="/media/5615/stackoverflow_captcha_thumb_498x365.jpg"  width="498"  height="365" alt="StackOverflow_Captcha_Thumb" class="imageNormal"/></a></p>

<p>... great stuff.</p>
]]></content:encoded></item><item><title>Examining and testing web services</title><link>http://www.trsdomain.dk//blog/2010/9/6/examining-and-testing-web-services.aspx</link><pubDate>Mon, 06 Sep 2010 15:16:33 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2010/9/6/examining-and-testing-web-services.aspx</guid><content:encoded><![CDATA[ 
<p>When working with web services you sometimes just want to make a
quick <em>"lets hit it, and see what it does"</em> test.</p>

<p>For that purpose <a href="http://www.wcfstorm.com"
title="WCF Storm WS testing tool">WCF Storm</a> is the must-have
tool, which a fellow developer recently pointed out to me. It
quickly generates a proxy and lets you specify parameters of
complex types, add custom headers and&nbsp; much more (none of
which the older <a href="http://webservicestudio.codeplex.com/"
target="_blank"
title="WebServiceStudio at CodePlex">WebServiceStudio</a> I used to
use could do)... It also lets speaks WCF.</p>

<p>The lite version does everything you are likely to need. The
paid versions contain functionality aimed at developers wanting to
integrate their web services in test or build routines, or
performance test them.</p>
]]></content:encoded></item><item><title>Afsted til Værløse</title><link>http://www.trsdomain.dk//blog/2010/4/7/afsted-til-vaerloese.aspx</link><pubDate>Wed, 07 Apr 2010 12:09:34 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2010/4/7/afsted-til-vaerloese.aspx</guid><content:encoded><![CDATA[ 
<p><img src="/media/4255/ryetvej_plantegning_217x289.jpg"  width="217"  height="289" alt="Ryetvej plantegning" class="alignright"/>Der er nu skrevet under,
financieret osv. - og jeg er dermed ejer af <a
href="http://maps.google.dk/maps?f=q&amp;source=s_q&amp;hl=da&amp;geocode=&amp;q=ryetvej+61+v%C3%A6rl%C3%B8se&amp;sll=56.010666,11.228027&amp;sspn=7.929169,19.753418&amp;ie=UTF8&amp;hq=&amp;hnear=Ryetvej+61,+3500,+V%C3%A6rl%C3%B8se&amp;ll=55.787819,12.364082&amp;spn=0.032334,0.077162&amp;t=h&amp;z=14"
 target="_blank" title="Ryetvej 61 på Google Maps">Ryetvej 61,
2.mf.</a><br />
 Pr. 1. juli tilbringer jeg derfor en del tid på den nye adresse,
hvor der skal males/hamres/skrues/find-selv-på-flere, hvorefter jeg
1. august endegyldigt forlader Vestergade *snøft* ;-)</p>

<p><img src="/media/4265/ryetvej_bagside_335x171.jpg"  width="335"  height="171" alt="Ryetvej bagside" class="alignleft"/></p>

<p>&nbsp;</p>
]]></content:encoded></item><item><title>Structuring extensive SOAP webservice APIs</title><link>http://www.trsdomain.dk//blog/2010/1/15/structuring-extensive-soap-webservice-apis.aspx</link><pubDate>Fri, 15 Jan 2010 15:39:22 GMT</pubDate><guid>http://www.trsdomain.dk//blog/2010/1/15/structuring-extensive-soap-webservice-apis.aspx</guid><content:encoded><![CDATA[ 
<p>Last year I spend some time building a webservice SOAP API for
the <a href="http://www.metimus.dk/" target="_blank">Metimus
system</a>. Although it only covers selected bits of the full
system it is still fairly extensive.</p>

<p>In the process I spend quite some time figuring out how to
structure SOAP services when you go beyond the simple
"RegisterForCompetition" type services... so I thought I'd share,
since my attempts at Googling a solution where unsuccessful.</p>

<p><strong>The problem I ran into</strong><br />
 When you build a webservice API, the natural instinct is to
attempt to make it look like a true OO API as much as possible. So
you will want to:</p>

<ul>
<li>Use objects for parameters and return types instead of
primitives, which is no problem with the complex types of WSDL</li>

<li>Partition your solution into multiple services, as you would
have multiple classes in an OO API (e.g. a CompanyHandler service,
a UserHandler service etc.)</li>
</ul>

<p>Now the problem arises when you try to e.g. use a return value
"User" object from one service operation as a parameter for an
operation on another service. Your solution will not compile!<br />
 The reason is that even though <em>you know</em> it's the same
class, the client proxy-generator does not (whether it is .NETs
WSDL.exe, Java or any other environment). There is no way around it
- at least not without making life miserable for the client
programmer (and the reason we wanted it OO'ish and shiny was to
make it easy :-)</p>

<p><strong>You have two basic choises:</strong> Either you
partition it into multiple services and use primitives for all
parameters - or you keep all operations in one big service and you
get to use objects for parameters and return values.</p>

<p>I ended up using the "one big service" option. To make it a bit
easier to maintain I then used the <a
href="http://www.4guysfromrolla.com/articles/071509-1.aspx"
target="_blank">partial class</a> feature of .NET, so I didn't end
up with one insanely large file.</p>

<p><strong>Further info and examples<br />
</strong> A full explanation of the problem including <a
href="http://www.experts-exchange.com/Programming/Languages/.NET/Web_Services/Q_24814102.html"
 target="_blank">sample code illustrating the problem</a> can be
seen here in <a
href="http://www.experts-exchange.com/Programming/Languages/.NET/Web_Services/Q_24814102.html"
 target="_blank">this Experts-Exchange question</a> I wrote. In
case you do not have an account, here are the resource-links that
was posted in the answer:</p>

<p>- <a
href="http://msdn.microsoft.com/en-us/library/aa480505.aspx"
target="_blank">Microsofts description</a><br />
 - <a
href="http://www.developerfusion.com/article/5155/web-services-interoperability-between-j2ee-and-net-part-3/3/"
 target="_blank">Another explanation</a></p>
]]></content:encoded></item></channel></rss>

