<?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>Ad hoc Geek &#187; .NET</title>
	<atom:link href="http://www.adhocgeek.com/tag/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.adhocgeek.com</link>
	<description>Approaching geekery in an ad hoc and improvisational manner.</description>
	<lastBuildDate>Fri, 30 Sep 2011 09:43:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>CSV Mangling in VB.NET</title>
		<link>http://www.adhocgeek.com/2011/02/196/</link>
		<comments>http://www.adhocgeek.com/2011/02/196/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 16:03:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[CSV Mangling]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://www.adhocgeek.com/?p=196</guid>
		<description><![CDATA[I&#8217;ll probably go to hell for this one since I imagine there are much better libraries out there to do the right thing, but I needed to write a quick and dirty function in VB.NET to split some quoted CSV into it&#8217;s constituent fields. This is horrible, but it works for the moment. 'A function [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll probably go to hell for this one since I imagine there are much better libraries out there to do the right thing, but I needed to write a quick and dirty function in VB.NET to split some quoted CSV into it&#8217;s constituent fields.</p>
<p>This is horrible, but it works for the moment.</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;">    <span style="color: #008000;">'A function to split a quoted comma delimited string into separate fields
</span>    <span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> GetFields(<span style="color: #151B8D; font-weight: bold;">ByVal</span> row <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>) <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span>()
        <span style="color: #151B8D; font-weight: bold;">Dim</span> fields <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #E56717; font-weight: bold;">New</span> List(Of <span style="color: #F660AB; font-weight: bold;">String</span>)
        <span style="color: #8D38C9; font-weight: bold;">If</span> row.Length = 0 <span style="color: #8D38C9; font-weight: bold;">Then</span>
            Return fields.ToArray()
        <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span>
&nbsp;
        <span style="color: #151B8D; font-weight: bold;">Dim</span> current <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Integer</span> = 0
        <span style="color: #151B8D; font-weight: bold;">Dim</span> buffer <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #E56717; font-weight: bold;">New</span> StringBuilder()
        <span style="color: #151B8D; font-weight: bold;">Dim</span> betweenQuotes <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span> = <span style="color: #00C2FF; font-weight: bold;">False</span>
        <span style="color: #151B8D; font-weight: bold;">Dim</span> eol <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Boolean</span> = <span style="color: #00C2FF; font-weight: bold;">False</span>
        <span style="color: #8D38C9; font-weight: bold;">While</span> <span style="color: #8D38C9; font-weight: bold;">Not</span> eol
&nbsp;
            <span style="color: #8D38C9; font-weight: bold;">Select</span> <span style="color: #8D38C9; font-weight: bold;">Case</span> row(current)
                <span style="color: #8D38C9; font-weight: bold;">Case</span> CChar(<span style="color: #800000;">&quot;&quot;</span><span style="color: #800000;">&quot;&quot;</span>)
                    betweenQuotes = <span style="color: #8D38C9; font-weight: bold;">Not</span> betweenQuotes
&nbsp;
                <span style="color: #8D38C9; font-weight: bold;">Case</span> CChar(<span style="color: #800000;">&quot;,&quot;</span>)
                    <span style="color: #8D38C9; font-weight: bold;">If</span> betweenQuotes <span style="color: #8D38C9; font-weight: bold;">Then</span>
                        buffer.Append(row(current))
                    <span style="color: #8D38C9; font-weight: bold;">Else</span>
                        fields.Add(buffer.ToString())
                        buffer = <span style="color: #E56717; font-weight: bold;">New</span> StringBuilder()
                    <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">If</span>
&nbsp;
                <span style="color: #8D38C9; font-weight: bold;">Case</span> <span style="color: #8D38C9; font-weight: bold;">Else</span>
                    buffer.Append(row(current))
&nbsp;
            <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">Select</span>
&nbsp;
            current += 1
            eol = (current = row.Length)
        <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">While</span>
&nbsp;
        <span style="color: #008000;">'Add the last field
</span>        fields.Add(buffer.ToString())
&nbsp;
        Return fields.ToArray()
    <span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></pre></div></div>

<p>NB, you&#8217;ll need to add these lines to the top of the file :</p>

<div class="wp_syntax"><div class="code"><pre class="vb" style="font-family:monospace;">Imports System.Text
Imports System.Collections.Generic</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.adhocgeek.com/2011/02/196/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing with Powershell</title>
		<link>http://www.adhocgeek.com/2011/01/playing-with-powershell/</link>
		<comments>http://www.adhocgeek.com/2011/01/playing-with-powershell/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 15:53:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[powershell]]></category>

		<guid isPermaLink="false">http://www.adhocgeek.com/?p=175</guid>
		<description><![CDATA[I&#8217;ve not actually used powershell before, but we had a requirement to store a list of security camera files and dates in a database so that we could track historical camera activity and this seemed like a good excuse to use it rather than writing a short C# executable. What I ended up with was [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve not actually used powershell before, but we had a requirement to store a list of security camera files and dates in a database so that we could track historical camera activity and this seemed like a good excuse to use it rather than writing a short C# executable.</p>
<p>What I ended up with was this :</p>

<div class="wp_syntax"><div class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #008000;"># Configuration</span>
<span style="color: #800080;">$camera_home</span> <span style="color: pink;">=</span> <span style="color: #800000;">&quot;C:\Recordings&quot;</span>;
<span style="color: #800080;">$connection_string</span> <span style="color: pink;">=</span> <span style="color: #800000;">&quot;Data Source=localhost;Initial Catalog=MyDatabase;Trusted_Connection=True&quot;</span>;
&nbsp;
<span style="color: #008000;"># Sanity Check</span>
<span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: pink;">!</span><span style="color: #000000;">&#40;</span><span style="color: #008080; font-weight: bold;">Test-Path</span> <span style="color: #800080;">$camera_home</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> 
<span style="color: #000000;">&#123;</span>
    <span style="color: #000000;">&#91;</span>Console<span style="color: #000000;">&#93;</span>::WriteLine<span style="color: #000000;">&#40;</span><span style="color: #800080;">$camera_home</span> <span style="color: pink;">+</span> <span style="color: #800000;">&quot; not found!&quot;</span><span style="color: #000000;">&#41;</span>; 
    <span style="color: #0000FF;">return</span>;
<span style="color: #000000;">&#125;</span>;
&nbsp;
<span style="color: #008000;"># Set up the SQL Connection</span>
<span style="color: #800080;">$conn</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">new-object</span> System.Data.SqlClient.SqlConnection<span style="color: #000000;">&#40;</span><span style="color: #800080;">$connection_string</span><span style="color: #000000;">&#41;</span>;
<span style="color: #800080;">$conn</span>.Open<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
<span style="color: #008000;"># Get a list of all cameras</span>
<span style="color: #800080;">$cameras</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">Get-ChildItem</span> <span style="color: #800080;">$camera_home</span>;
&nbsp;
<span style="color: #008000;"># Iterate over the list</span>
<span style="color: #0000FF;">foreach</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$camera</span> <span style="color: #0000FF;">in</span> <span style="color: #800080;">$cameras</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #000000;">&#91;</span>Console<span style="color: #000000;">&#93;</span>::WriteLine<span style="color: #000000;">&#40;</span><span style="color: #800080;">$camera</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #800080;">$guid</span> <span style="color: pink;">=</span> <span style="color: #800080;">$camera</span>.Name;
&nbsp;
    <span style="color: #008000;"># Check whether the current camera exists in the database.</span>
    <span style="color: #800080;">$camera_getid</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">new-object</span> System.Data.SqlClient.SqlCommand<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;select ID from dbo.Camera where CameraGUID = @CameraGUID&quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$conn</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #800080;">$camera_getid</span>.Parameters.Add<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;@CameraGUID&quot;</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Data.SqlDbType<span style="color: #000000;">&#93;</span><span style="color: #800000;">&quot;NVarChar&quot;</span><span style="color: #000000;">&#41;</span>.Value <span style="color: pink;">=</span> <span style="color: #800080;">$guid</span>;
    <span style="color: #800080;">$id</span> <span style="color: pink;">=</span> <span style="color: #800080;">$camera_getid</span>.ExecuteScalar<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$id</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800080;">$Null</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #008000;"># Create a new camera record</span>
        <span style="color: #800080;">$camera_create</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">new-object</span> System.Data.SqlClient.SqlCommand<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;insert into dbo.Camera(CameraGUID, CameraName) values(@CameraGUID, 'New Camera')&quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$conn</span><span style="color: #000000;">&#41;</span>;
        <span style="color: #800080;">$camera_create</span>.Parameters.Add<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;@CameraGUID&quot;</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Data.SqlDbType<span style="color: #000000;">&#93;</span><span style="color: #800000;">&quot;NVarChar&quot;</span><span style="color: #000000;">&#41;</span>.Value <span style="color: pink;">=</span> <span style="color: #800080;">$guid</span>;
        <span style="color: #800080;">$camera_create</span>.ExecuteNonQuery<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
        <span style="color: #800080;">$id</span> <span style="color: pink;">=</span> <span style="color: #800080;">$camera_getid</span>.ExecuteScalar<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;        
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #008000;"># Get the date of the last recording we have a record for</span>
    <span style="color: #800080;">$camera_getlastrecording</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">new-object</span> System.Data.SqlClient.SqlCommand<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;select case when Max(RecordingDate) is null then convert(datetime, '1/1/2001', 103) else MAX(RecordingDate) end from dbo.CameraData where CameraID = @CameraID&quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$conn</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #800080;">$camera_getlastrecording</span>.Parameters.Add<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;@CameraID&quot;</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Data.SqlDbType<span style="color: #000000;">&#93;</span><span style="color: #800000;">&quot;Int&quot;</span><span style="color: #000000;">&#41;</span>.Value <span style="color: pink;">=</span> <span style="color: #800080;">$id</span>;
    <span style="color: #800080;">$lastrecording</span> <span style="color: pink;">=</span> <span style="color: #800080;">$camera_getlastrecording</span>.ExecuteScalar<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #000000;">&#91;</span>Console<span style="color: #000000;">&#93;</span>::WriteLine<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #008080;">String</span><span style="color: #000000;">&#93;</span>::Concat<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;    Last recording date : &quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$lastrecording</span> <span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
    <span style="color: #008000;"># Get a list of new recordings</span>
    <span style="color: #800080;">$recordings</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">Get-ChildItem</span> <span style="color: #008080; font-style: italic;">-recurse</span> <span style="color: #008080; font-style: italic;">-include</span> <span style="color: #800000;">&quot;*.acsm&quot;</span> <span style="color: #800080;">$camera_home</span>\<span style="color: #800080;">$camera</span> <span style="color: pink;">|</span> <span style="color: #008080; font-weight: bold;">Where-Object</span> <span style="color: #000000;">&#123;</span><span style="color: #000080;">$_</span>.CreationTime <span style="color: #FF0000;">-gt</span> <span style="color: #800080;">$lastrecording</span><span style="color: #000000;">&#125;</span>;
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$recordings</span> <span style="color: #FF0000;">-eq</span> <span style="color: #800080;">$Null</span><span style="color: #000000;">&#41;</span> 
    <span style="color: #000000;">&#123;</span> 
        <span style="color: #000000;">&#91;</span>Console<span style="color: #000000;">&#93;</span>::WriteLine<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #008080;">String</span><span style="color: #000000;">&#93;</span>::Concat<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;    No new recordings found.&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;
        <span style="color: #0000FF;">continue</span> 
    <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#91;</span>Console<span style="color: #000000;">&#93;</span>::WriteLine<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #008080;">String</span><span style="color: #000000;">&#93;</span>::Concat<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;    &quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$recordings</span>.Count<span style="color: pink;">,</span> <span style="color: #800000;">&quot; new recordings found.&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;
&nbsp;
    <span style="color: #008000;"># Insert new recordings into the database</span>
    <span style="color: #0000FF;">foreach</span><span style="color: #000000;">&#40;</span><span style="color: #800080;">$recording</span> <span style="color: #0000FF;">in</span> <span style="color: #800080;">$recordings</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #000000;">&#91;</span>Console<span style="color: #000000;">&#93;</span>::WriteLine<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #008080;">String</span><span style="color: #000000;">&#93;</span>::Concat<span style="color: #000000;">&#40;</span><span style="color: #800080;">$recording</span><span style="color: pink;">,</span> <span style="color: #800000;">&quot;,&quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$recording</span>.CreationTime.ToString<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;dd/MM/yyyy HH:mm:ss.FF&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>;
        <span style="color: #800080;">$recording_create</span> <span style="color: pink;">=</span> <span style="color: #008080; font-weight: bold;">new-object</span> System.Data.SqlClient.SqlCommand<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;insert into dbo.CameraData(CameraID, RecordingName, RecordingDate) values(@CameraID, @RecordingName, @RecordingDate)&quot;</span><span style="color: pink;">,</span> <span style="color: #800080;">$conn</span><span style="color: #000000;">&#41;</span>;
        <span style="color: #800080;">$recording_create</span>.Parameters.Add<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;@CameraID&quot;</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Data.SqlDbType<span style="color: #000000;">&#93;</span><span style="color: #800000;">&quot;Int&quot;</span><span style="color: #000000;">&#41;</span>.Value <span style="color: pink;">=</span> <span style="color: #800080;">$id</span>;
        <span style="color: #800080;">$recording_create</span>.Parameters.Add<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;@RecordingName&quot;</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Data.SqlDbType<span style="color: #000000;">&#93;</span><span style="color: #800000;">&quot;NVarChar&quot;</span><span style="color: #000000;">&#41;</span>.Value <span style="color: pink;">=</span> <span style="color: #800080;">$recording</span>.FullName;
        <span style="color: #800080;">$recording_create</span>.Parameters.Add<span style="color: #000000;">&#40;</span><span style="color: #800000;">&quot;@RecordingDate&quot;</span><span style="color: pink;">,</span> <span style="color: #000000;">&#91;</span>System.Data.SqlDbType<span style="color: #000000;">&#93;</span><span style="color: #800000;">&quot;DateTime&quot;</span><span style="color: #000000;">&#41;</span>.Value <span style="color: pink;">=</span> <span style="color: #800080;">$recording</span>.CreationTime;
        <span style="color: #800080;">$recording_create</span>.ExecuteNonQuery<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>;
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Probably the most interesting thing about this post was how long it took to actually make it because of this :</p>
<p><a href="http://wordpress.stackexchange.com/questions/6421/how-can-a-single-line-in-a-blog-post-take-down-my-server/6428#6428">http://wordpress.stackexchange.com/questions/6421/how-can-a-single-line-in-a-blog-post-take-down-my-server/6428#6428</a></p>
<p>I suspect this kind of thing is going to reoccur if I post anything else with SQL in it, but unfortunately, I don&#8217;t have the ability to switch off the ModSecurity rules&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocgeek.com/2011/01/playing-with-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uploading large files with ASP.NET</title>
		<link>http://www.adhocgeek.com/2009/10/uploading-large-files-with-asp-net/</link>
		<comments>http://www.adhocgeek.com/2009/10/uploading-large-files-with-asp-net/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 11:29:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[byte stream processing]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[IHttpModule]]></category>
		<category><![CDATA[Large File Uploads]]></category>

		<guid isPermaLink="false">http://www.adhocgeek.com/?p=158</guid>
		<description><![CDATA[I&#8217;ve recently had a need for users of an intranet application to upload comparatively large text files (1-200MB) to a web server. There are only a couple of ways I can think of to get around the limits imposed by IIS and ASP.NET without writing code : train the users to upload smaller files which [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently had a need for users of an intranet application to upload comparatively large text files (1-200MB) to a web server. There are only a couple of ways I can think of to get around the limits imposed by IIS and ASP.NET without writing code : train the users to upload smaller files which could be concatenated at the server, or allow the users to &#8220;upload&#8221; from a network share which the server has access to. These are obviously inelegant solutions, and after a little research I&#8217;ve found that the necessary code to enable large uploads yourself is surprisingly easy to write.</p>
<p><a href="http://weblogs.asp.net/jgalloway/default.aspx">Jon Galloway</a> has written a useful article which gives a more complete and eloquent view of the ASP.NET large file upload problem than I have time for <a href="http://weblogs.asp.net/jgalloway/archive/2008/01/08/large-file-uploads-in-asp-net.aspx">here</a>. Particularly of interest is the discussion he links to, titled <a href="http://forums.asp.net/t/55127.aspx?PageIndex=1">&#8220;HttpHandler or HttpModule for file upload, large files, progress indicator?&#8221;</a>. I&#8217;ve adapted or rewritten some of the suggested code from there for my solution. I&#8217;m particularly indebted to <a href="http://forums.asp.net/members/TravisWhidden.aspx">Travis Whidden</a> whose code is much more complete than mine (it handles multiple files, for a start). Part of the reason I ended up rewriting it is because I didn&#8217;t think this solution handled a particular edge case, but I also needed to understand what it was doing, and the best way for me to do that was rewrite from scratch (this took me about a day of thinking, poking around and testing &#8211; I don&#8217;t claim to be a fast learner <img src='http://www.adhocgeek.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>Essentially the code consists of two classes, UploadModule and RequestProcessor, along with some minor changes in the web.config file :</p>
<h3>UploadModule</h3>
<p>In order to intercept the HttpRequest and deal with it in a stream-wise fashion, we have to implement an IHttpModule :</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Diagnostics</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Text</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Web</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Reflection</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">namespace</span> MyIntranetSite
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> UploadModule <span style="color: #008000;">:</span> IHttpModule
    <span style="color: #008000;">&#123;</span>
        <span style="color: #008080;">#region IHttpModule Members</span>
&nbsp;
        <span style="color: #6666cc; font-weight: bold;">void</span> IHttpModule<span style="color: #008000;">.</span><span style="color: #0000FF;">Dispose</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #6666cc; font-weight: bold;">void</span> IHttpModule<span style="color: #008000;">.</span><span style="color: #0000FF;">Init</span><span style="color: #008000;">&#40;</span>HttpApplication context<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            context<span style="color: #008000;">.</span><span style="color: #0000FF;">BeginRequest</span> <span style="color: #008000;">+=</span> <span style="color: #008000;">new</span> EventHandler<span style="color: #008000;">&#40;</span>context_BeginRequest<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #6666cc; font-weight: bold;">void</span>  context_BeginRequest<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, EventArgs e<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            HttpApplication application <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>HttpApplication<span style="color: #008000;">&#41;</span> sender<span style="color: #008000;">;</span>
            HttpContext context <span style="color: #008000;">=</span> application<span style="color: #008000;">.</span><span style="color: #0000FF;">Context</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>context<span style="color: #008000;">.</span><span style="color: #0000FF;">Request</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ContentType</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IndexOf</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;multipart/form-data&quot;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">//Not our bag, baby.</span>
                <span style="color: #0600FF; font-weight: bold;">return</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">try</span>
            <span style="color: #008000;">&#123;</span>
                HttpWorkerRequest workerRequest <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>HttpWorkerRequest<span style="color: #008000;">&#41;</span> context<span style="color: #008000;">.</span><span style="color: #0000FF;">GetType</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">GetProperty</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;WorkerRequest&quot;</span>, BindingFlags<span style="color: #008000;">.</span><span style="color: #0000FF;">Instance</span> <span style="color: #008000;">|</span> BindingFlags<span style="color: #008000;">.</span><span style="color: #0000FF;">NonPublic</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">GetValue</span><span style="color: #008000;">&#40;</span>context, <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>workerRequest<span style="color: #008000;">.</span><span style="color: #0000FF;">HasEntityBody</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    <span style="color: #6666cc; font-weight: bold;">long</span> defaultBuffer <span style="color: #008000;">=</span> <span style="color: #FF0000;">500000</span><span style="color: #008000;">;</span> 
                    <span style="color: #6666cc; font-weight: bold;">long</span> contentLength <span style="color: #008000;">=</span> <span style="color: #6666cc; font-weight: bold;">long</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Parse</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>workerRequest<span style="color: #008000;">.</span><span style="color: #0000FF;">GetKnownRequestHeader</span><span style="color: #008000;">&#40;</span>HttpWorkerRequest<span style="color: #008000;">.</span><span style="color: #0000FF;">HeaderContentLength</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                    <span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> preloadedBufferData <span style="color: #008000;">=</span> workerRequest<span style="color: #008000;">.</span><span style="color: #0000FF;">GetPreloadedEntityBody</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                    RequestProcessor rp <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> RequestProcessor<span style="color: #008000;">&#40;</span>contentLength<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                    rp<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadBuffer</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> preloadedBufferData<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
                    <span style="color: #6666cc; font-weight: bold;">long</span> remaining <span style="color: #008000;">=</span> contentLength <span style="color: #008000;">-</span> preloadedBufferData<span style="color: #008000;">.</span><span style="color: #0000FF;">Length</span><span style="color: #008000;">;</span>
                    <span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> bufferData<span style="color: #008000;">;</span>
                    <span style="color: #0600FF; font-weight: bold;">while</span> <span style="color: #008000;">&#40;</span>remaining <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #008000;">&#123;</span>
                        bufferData <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> <span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#40;</span>remaining <span style="color: #008000;">&gt;</span> defaultBuffer<span style="color: #008000;">&#41;</span><span style="color: #008000;">?</span> defaultBuffer <span style="color: #008000;">:</span> remaining<span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
                        remaining <span style="color: #008000;">-=</span> bufferData<span style="color: #008000;">.</span><span style="color: #0000FF;">Length</span><span style="color: #008000;">;</span>
                        workerRequest<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadEntityBody</span><span style="color: #008000;">&#40;</span>bufferData, bufferData<span style="color: #008000;">.</span><span style="color: #0000FF;">Length</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                        rp<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadBuffer</span><span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> bufferData<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                    <span style="color: #008000;">&#125;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
            <span style="color: #0600FF; font-weight: bold;">catch</span><span style="color: #008000;">&#40;</span>Exception ex<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                EventLog<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteEntry</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Custom ASP.NET Upload Module&quot;</span>, ex<span style="color: #008000;">.</span><span style="color: #0000FF;">Message</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            context<span style="color: #008000;">.</span><span style="color: #0000FF;">Response</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Redirect</span><span style="color: #008000;">&#40;</span>context<span style="color: #008000;">.</span><span style="color: #0000FF;">Request</span><span style="color: #008000;">.</span><span style="color: #0000FF;">RawUrl</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008080;">#endregion</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>This handles ALL &#8220;multipart/form-data&#8221; requests at the moment. You would probably want to check the url of the request and match it against a list of expected pages, otherwise all of your web requests (that is, every postback) would get processed by this module, and much of your code would be bypassed!</p>
<h3>RequestProcessor</h3>
<p>This class takes a series of byte array buffers and parses them for a start and end pattern. Hopefully, I&#8217;ve commented my code well enough for it to be read and understood. However, I should say that this only deals with single file uploads at the moment and expects to be able to write to &#8220;C:\temp\&#8221;. It would be possible to improve the code to handle multiple files and making the upload directory configurable would be fairly trivial, but I think it&#8217;s more useful as a learning tool if I keep it simple for now.</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Diagnostics</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Collections.Generic</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.IO</span><span style="color: #008000;">;</span>
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Text</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF; font-weight: bold;">namespace</span> MyIntranetSite
<span style="color: #008000;">&#123;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">//</span>
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// Takes byte[] chunks from an HTTP request and processes them looking for (currently) the first file.</span>
    <span style="color: #008080; font-style: italic;">/// Each file will be wrapped by the lines :</span>
    <span style="color: #008080; font-style: italic;">/// (start) &quot;Content-Type: [some content type]\r\n&quot;</span>
    <span style="color: #008080; font-style: italic;">/// (end) &quot;-----------------------------[a form post ID]\r\n\r\n&quot; </span>
    <span style="color: #008080; font-style: italic;">///       (that's 29 &quot;-&quot;s followed by a number, followed by 2 * carriage return + newline</span>
    <span style="color: #008080; font-style: italic;">/// </span>
    <span style="color: #008080; font-style: italic;">/// Problems arise because the start and end patterns could span two buffers.</span>
    <span style="color: #008080; font-style: italic;">/// This means we can't write from the latest buffer - we have to always be writing from the previous buffer,</span>
    <span style="color: #008080; font-style: italic;">/// since we can never know if the latest buffer (assuming there are more bytes to read) contains the start of the</span>
    <span style="color: #008080; font-style: italic;">/// end pattern, but not all of it.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> RequestProcessor <span style="color: #008000;">:</span> IDisposable 
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">long</span> Length <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #0600FF; font-weight: bold;">private</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">long</span> BytesRead <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> <span style="color: #0600FF; font-weight: bold;">private</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span> FinishedFiles <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">private</span> BufferChunk previous<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">bool</span> _startFound <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">bool</span> _endFound <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span> startPatternBegin<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span> startPatternEnd<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span> endPattern<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> FileStream currentFileStream<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">string</span> currentFileName <span style="color: #008000;">=</span> Guid<span style="color: #008000;">.</span><span style="color: #0000FF;">NewGuid</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;.bin&quot;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> RequestProcessor<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">long</span> length<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            Length <span style="color: #008000;">=</span> length<span style="color: #008000;">;</span>
            BytesRead <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
            startPatternBegin <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>Encoding<span style="color: #008000;">.</span><span style="color: #0000FF;">UTF8</span><span style="color: #008000;">.</span><span style="color: #0000FF;">GetBytes</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Content-Type: &quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            startPatternEnd <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>Encoding<span style="color: #008000;">.</span><span style="color: #0000FF;">UTF8</span><span style="color: #008000;">.</span><span style="color: #0000FF;">GetBytes</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\r</span><span style="color: #008080; font-weight: bold;">\n</span><span style="color: #008080; font-weight: bold;">\r</span><span style="color: #008080; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> ReadBuffer<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> <span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> buffer<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>_endFound<span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">return</span><span style="color: #008000;">;</span>
&nbsp;
            BufferChunk current <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> BufferChunk<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> buffer<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>previous <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">//first buffer chunk</span>
                <span style="color: #008080; font-style: italic;">//the first line of this will give the form content separator, which is also the endPattern</span>
                <span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
                endPattern <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #0600FF; font-weight: bold;">while</span> <span style="color: #008000;">&#40;</span>current<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #008000;">!=</span> Encoding<span style="color: #008000;">.</span><span style="color: #0000FF;">UTF8</span><span style="color: #008000;">.</span><span style="color: #0000FF;">GetBytes</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\r</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#91;</span><span style="color: #FF0000;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    endPattern<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>current<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                    i<span style="color: #008000;">++;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">//Merge the previous and current buffers</span>
            List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span> mergedBuffers <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>previous <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span> mergedBuffers<span style="color: #008000;">.</span><span style="color: #0000FF;">AddRange</span><span style="color: #008000;">&#40;</span>previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            mergedBuffers<span style="color: #008000;">.</span><span style="color: #0000FF;">AddRange</span><span style="color: #008000;">&#40;</span>current<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>_startFound<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">//Look for start pattern in the current buffer.</span>
                <span style="color: #008080; font-style: italic;">//It could span this buffer and the one before (in which case the start point is in THIS buffer)</span>
                <span style="color: #008080; font-style: italic;">//or it could span this buffer and the next (in which case the start point is in the NEXT buffer)</span>
                <span style="color: #008080; font-style: italic;">//The latter case has to be checked when the next buffer comes in.</span>
&nbsp;
                <span style="color: #6666cc; font-weight: bold;">int</span> startBegin<span style="color: #008000;">;</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>startBegin <span style="color: #008000;">=</span> FindBytePattern<span style="color: #008000;">&#40;</span>mergedBuffers, startPatternBegin, <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">!=</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    <span style="color: #008080; font-style: italic;">//found a content-type declaration, look for the end of that line :</span>
                    <span style="color: #6666cc; font-weight: bold;">int</span> startEnd<span style="color: #008000;">;</span>
                    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>startEnd <span style="color: #008000;">=</span> FindBytePattern<span style="color: #008000;">&#40;</span>mergedBuffers, startPatternEnd, startBegin <span style="color: #008000;">+</span> startPatternBegin<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">!=</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #008000;">&#123;</span>
                        <span style="color: #008080; font-style: italic;">//found the end of the line</span>
                        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>startEnd <span style="color: #008000;">+</span> startPatternEnd<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">&lt;</span> mergedBuffers<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">-</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span>
                        <span style="color: #008000;">&#123;</span>
                            <span style="color: #6666cc; font-weight: bold;">int</span> startByte <span style="color: #008000;">=</span> startEnd <span style="color: #008000;">+</span> startPatternEnd<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
                            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>previous <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
                            <span style="color: #008000;">&#123;</span>
                                current<span style="color: #008000;">.</span><span style="color: #0000FF;">Start</span> <span style="color: #008000;">=</span> startByte <span style="color: #008000;">-</span> previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
                            <span style="color: #008000;">&#125;</span>
                            <span style="color: #0600FF; font-weight: bold;">else</span>
                            <span style="color: #008000;">&#123;</span>
                                current<span style="color: #008000;">.</span><span style="color: #0000FF;">Start</span> <span style="color: #008000;">=</span> startByte<span style="color: #008000;">;</span>
                            <span style="color: #008000;">&#125;</span>
                            _startFound <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
                        <span style="color: #008000;">&#125;</span>
                        <span style="color: #008080; font-style: italic;">// else the start byte is in the next buffer.</span>
                    <span style="color: #008000;">&#125;</span>
                <span style="color: #008000;">&#125;</span>
&nbsp;
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>_startFound<span style="color: #008000;">&#41;</span> current<span style="color: #008000;">.</span><span style="color: #0000FF;">Start</span> <span style="color: #008000;">=</span> current<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>_startFound <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">!</span>_endFound<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">//Look for the end pattern in the current buffer</span>
                <span style="color: #008080; font-style: italic;">//As with the start it could span beginning (in which case the last byte is in the PREVIOUS buffer)</span>
                <span style="color: #008080; font-style: italic;">//Or it could span the end (in which case the last byte is in THIS buffer)</span>
                <span style="color: #008080; font-style: italic;">//The latter case has to be checked when the next buffer comes in.</span>
&nbsp;
                <span style="color: #6666cc; font-weight: bold;">int</span> endBegin<span style="color: #008000;">;</span>
                <span style="color: #6666cc; font-weight: bold;">int</span> searchStart <span style="color: #008000;">=</span> previous <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">?</span> previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Start</span> <span style="color: #008000;">:</span> current<span style="color: #008000;">.</span><span style="color: #0000FF;">Start</span><span style="color: #008000;">;</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>endBegin <span style="color: #008000;">=</span> FindBytePattern<span style="color: #008000;">&#40;</span>mergedBuffers, endPattern, searchStart<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">!=</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    <span style="color: #6666cc; font-weight: bold;">int</span> endByte <span style="color: #008000;">=</span> endBegin <span style="color: #008000;">-</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
                    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>previous <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #008000;">&#123;</span>
                        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>endByte <span style="color: #008000;">&lt;</span> previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#41;</span>
                            previous<span style="color: #008000;">.</span><span style="color: #0000FF;">End</span> <span style="color: #008000;">=</span> endByte<span style="color: #008000;">;</span>
                        <span style="color: #0600FF; font-weight: bold;">else</span>
                            current<span style="color: #008000;">.</span><span style="color: #0000FF;">End</span> <span style="color: #008000;">=</span> endByte <span style="color: #008000;">-</span> previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
                    <span style="color: #008000;">&#125;</span>
                    <span style="color: #0600FF; font-weight: bold;">else</span>
                    <span style="color: #008000;">&#123;</span>
                        current<span style="color: #008000;">.</span><span style="color: #0000FF;">End</span> <span style="color: #008000;">=</span> endByte<span style="color: #008000;">;</span>
                    <span style="color: #008000;">&#125;</span>
                    _endFound <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
                <span style="color: #008080; font-style: italic;">// else the end byte is in the next buffer.</span>
&nbsp;
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>_endFound <span style="color: #008000;">&amp;&amp;</span> previous <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span> previous<span style="color: #008000;">.</span><span style="color: #0000FF;">End</span> <span style="color: #008000;">=</span> previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
            BytesRead <span style="color: #008000;">+=</span> current<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #008080; font-style: italic;">//FILE CREATION</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>previous <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span> <span style="color: #008000;">&amp;&amp;</span> _startFound <span style="color: #008000;">&amp;&amp;</span> previous<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteBytes</span> <span style="color: #008000;">&gt;</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">//Write out the previous buffer from Start to End</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>currentFileStream <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    currentFileStream <span style="color: #008000;">=</span> File<span style="color: #008000;">.</span><span style="color: #0000FF;">OpenWrite</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">@&quot;C:\temp\&quot;</span> <span style="color: #008000;">+</span> currentFileName<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
                currentFileStream<span style="color: #008000;">.</span><span style="color: #0000FF;">Write</span><span style="color: #008000;">&#40;</span>previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToArray</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, previous<span style="color: #008000;">.</span><span style="color: #0000FF;">Start</span>, previous<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteBytes</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>_startFound <span style="color: #008000;">&amp;&amp;</span> _endFound <span style="color: #008000;">||</span> BytesRead <span style="color: #008000;">==</span> Length<span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #008080; font-style: italic;">//Write out the current buffer from Start to End</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>currentFileStream <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    currentFileStream <span style="color: #008000;">=</span> File<span style="color: #008000;">.</span><span style="color: #0000FF;">OpenWrite</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">@&quot;C:\temp\&quot;</span> <span style="color: #008000;">+</span> currentFileName<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
                currentFileStream<span style="color: #008000;">.</span><span style="color: #0000FF;">Write</span><span style="color: #008000;">&#40;</span>current<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToArray</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, current<span style="color: #008000;">.</span><span style="color: #0000FF;">Start</span>, current<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteBytes</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                currentFileStream<span style="color: #008000;">.</span><span style="color: #0000FF;">Close</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                currentFileStream<span style="color: #008000;">.</span><span style="color: #0000FF;">Dispose</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            previous <span style="color: #008000;">=</span> current<span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">int</span> FindBytePattern<span style="color: #008000;">&#40;</span>List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span> container, List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span> pattern, <span style="color: #6666cc; font-weight: bold;">int</span> startIndex<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #6666cc; font-weight: bold;">int</span> i, position<span style="color: #008000;">;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>pattern<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">&gt;</span> container<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">-</span> startIndex<span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span>position <span style="color: #008000;">=</span> startIndex<span style="color: #008000;">;</span> position <span style="color: #008000;">&lt;</span> container<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span> position<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>container<span style="color: #008000;">&#91;</span>position<span style="color: #008000;">&#93;</span> <span style="color: #008000;">==</span> pattern<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
                <span style="color: #008000;">&#123;</span>
                    <span style="color: #0600FF; font-weight: bold;">for</span><span style="color: #008000;">&#40;</span>i <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> pattern<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
                    <span style="color: #008000;">&#123;</span>
                        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>position <span style="color: #008000;">+</span> i <span style="color: #008000;">==</span> container<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span> <span style="color: #008000;">||</span> pattern<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #008000;">!=</span> container<span style="color: #008000;">&#91;</span>position <span style="color: #008000;">+</span> i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">break</span><span style="color: #008000;">;</span>
                    <span style="color: #008000;">&#125;</span>
                    <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>i <span style="color: #008000;">==</span> pattern<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">return</span> position<span style="color: #008000;">;</span>
                <span style="color: #008000;">&#125;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008080;">#region IDisposable Members</span>
&nbsp;
        <span style="color: #6666cc; font-weight: bold;">void</span> IDisposable<span style="color: #008000;">.</span><span style="color: #0000FF;">Dispose</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>currentFileStream <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                currentFileStream<span style="color: #008000;">.</span><span style="color: #0000FF;">Close</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
                currentFileStream<span style="color: #008000;">.</span><span style="color: #0000FF;">Dispose</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #008080;">#endregion</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> BufferChunk
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span> Data<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> Start<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> End<span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> WriteBytes <span style="color: #008000;">&#123;</span> get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> End <span style="color: #008000;">-</span> Start<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span> <span style="color: #008000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">public</span> BufferChunk<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">ref</span> <span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> buffer<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            Data <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">byte</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            Start <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span>
            End <span style="color: #008000;">=</span> Data<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>These files can sit within your web project or in a separate assembly if you want. Personally I&#8217;d rather have them sitting with the web project since that makes them more straightforward to debug and more obvious as to where they belong.</p>
<h3>Web.Config changes</h3>
<p>This is almost laughably trivial :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;httpModules<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;add</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;UploadModule&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;MyIntranetSite.UploadModule&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/httpModules<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>And that&#8217;s it! There&#8217;s obviously a lot more that could be done (such as the progress indicator Travis incorporated), but this seems like a decent start to me.</p>
<p>Ideally, ASP.NET 3.0(?) and IIS 7.0 would address this kind of problem once and for all, but I&#8217;m not holding my breath. I also suspect a lot of businesses will remain on IE6.0, IIS 5/6 and ASP.NET 2.0 for another few years, so this approach will remain relevant a little while longer.</p>
<h3>Update (a warning)</h3>
<p>It&#8217;s entirely possible that the parser will bomb out with some kind of error on occasion. If this happens when the number of bytes left to process is greater than the ASP.NET maxRequestLength (or the IIS request length) then the site will (seemingly) silently fail and you&#8217;ll get the dreaded &#8220;Connection was reset&#8221; error page!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocgeek.com/2009/10/uploading-large-files-with-asp-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing with IDataReader and SqlBulkCopy</title>
		<link>http://www.adhocgeek.com/2009/08/playing-with-idatareader-and-sqlbulkcopy/</link>
		<comments>http://www.adhocgeek.com/2009/08/playing-with-idatareader-and-sqlbulkcopy/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 13:57:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[IDataReader]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[SqlBulkCopy]]></category>

		<guid isPermaLink="false">http://www.adhocgeek.com/?p=108</guid>
		<description><![CDATA[For importing huge amounts of data into SQL Server, there&#8217;s really nothing quite like SqlBulkCopy. I&#8217;ve recently had a need to manipulate a (roughly) 330,000 line CSV file and import the results of that manipulation into a single table. Doing this record by record can take minutes, but with SqlBulkCopy, importing that many records can [...]]]></description>
			<content:encoded><![CDATA[<p>For importing huge amounts of data into SQL Server, there&#8217;s really nothing quite like <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx">SqlBulkCopy</a>. I&#8217;ve recently had a need to manipulate a (roughly) 330,000 line CSV file and import the results of that manipulation into a single table. Doing this record by record can take <em>minutes</em>, but with <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx">SqlBulkCopy</a>, importing that many records can be done in about 4 seconds on my development machine (and it&#8217;s definitely not the fastest PC in the world).</p>
<p><strong>Out of Memory</strong></p>
<p>Originally I was reading in the file, manipulating the data and writing out another CSV file I could use with DTS. However, <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.writetoserver.aspx">SqlBulkCopy.WriteToServer</a> doesn&#8217;t take a CSV file directly, it only takes either a <a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx">DataTable</a>, <a href="http://msdn.microsoft.com/en-us/library/system.data.datarow.aspx">DataRow</a>[] or <a href="http://msdn.microsoft.com/en-us/library/system.data.idatareader.aspx">IDataReader</a>, so at first, while writing out the CSV file I was also building up a <a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx">DataTable</a> to pass to it. For a file like mine of only a few hundred thousand records, it wasn&#8217;t a big problem to build that <a href="http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx">DataTable</a> in memory &#8211; it was only taking a few hundred MB &#8211; but it occurred to me that there could be a problem if the number of records increased modestly to a million or so. In fact, with a file of only 4 million records, I&#8217;d probably be looking at a <a href="http://msdn.microsoft.com/en-us/library/system.outofmemoryexception.aspx">System.OutOfMemoryException</a>.</p>
<p><strong>IDataReader</strong></p>
<p>The solution to this problem is to write a class which implements <a href="http://msdn.microsoft.com/en-us/library/system.data.idatareader.aspx">IDataReader</a> and pass this to SqlBulkCopy. There are <a href="http://www.google.co.uk/search?hl=en&#038;q=CSVDataReader+C%23">a few implementations out there already</a>, but I couldn&#8217;t find anything both free and in C#. I didn&#8217;t look terribly hard though, and I was curious to try writing a basic implementation myself just to see how difficult it would be.<br />
It turns out it&#8217;s not very difficult at all, it depends on how much effort you want to put in. For a simple spike like this I just wanted to see how long it took to implement enough of IDataReader for SqlBulkCopy to work so I could then see how much memory was being used. This is (part of) what I ended up with :</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> CSVDataReader <span style="color: #008000;">:</span> IDataReader
<span style="color: #008000;">&#123;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> StreamReader stream<span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>, <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span> columnsByName <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">string</span>,<span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">int</span>, <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span> columnsByOrdinal <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Dictionary<span style="color: #008000;">&lt;</span><span style="color: #6666cc; font-weight: bold;">int</span>,<span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> currentRow<span style="color: #008000;">;</span>
    <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">bool</span> _isClosed <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> CSVDataReader<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> fileName<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>File<span style="color: #008000;">.</span><span style="color: #0000FF;">Exists</span><span style="color: #008000;">&#40;</span>fileName<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
            <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> Exception<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;File [&quot;</span> <span style="color: #008000;">+</span> fileName <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;] does not exist.&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">stream</span> <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> StreamReader<span style="color: #008000;">&#40;</span>fileName<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> headers <span style="color: #008000;">=</span> stream<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadLine</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Split</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">','</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> i<span style="color: #008000;">=</span><span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> headers<span style="color: #008000;">.</span><span style="color: #0000FF;">Length</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            columnsByName<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>headers<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span>, i<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
            columnsByOrdinal<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>i, headers<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #008000;">&#125;</span>
&nbsp;
        _isClosed <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> Close<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>stream <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span> stream<span style="color: #008000;">.</span><span style="color: #0000FF;">Close</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        _isClosed <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> FieldCount
    <span style="color: #008000;">&#123;</span>
        get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> columnsByName<span style="color: #008000;">.</span><span style="color: #0000FF;">Count</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// This is the main function that does the work - it reads in the next line of data and parses the values into ordinals.</span>
    <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
    <span style="color: #008080; font-style: italic;">/// &lt;returns&gt;A value indicating whether the EOF was reached or not.&lt;/returns&gt;</span>
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">bool</span> Read<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>stream <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>stream<span style="color: #008000;">.</span><span style="color: #0000FF;">EndOfStream</span><span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span>
&nbsp;
        currentRow <span style="color: #008000;">=</span> stream<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadLine</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Split</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">','</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">object</span> GetValue<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> currentRow<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> GetName<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> columnsByOrdinal<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> GetOrdinal<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> name<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0600FF; font-weight: bold;">return</span> columnsByName<span style="color: #008000;">&#91;</span>name<span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #008080; font-style: italic;">//Other IDataReader methods/properties here, but all throwing not implemented exceptions.</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>It turns out you only need to implement these few properties and methods for SqlBulkCopy (I&#8217;m not even sure you need implement this much). Once I had this, it was a mere four lines to import the CSV file into SQL Server :</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;">SqlBulkCopy sbc <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> SqlBulkCopy<span style="color: #008000;">&#40;</span>mySqlConnection<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span>
sbc<span style="color: #008000;">.</span><span style="color: #0000FF;">DestinationTableName</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;MyTable&quot;</span><span style="color: #008000;">;</span>
sbc<span style="color: #008000;">.</span><span style="color: #0000FF;">BulkCopyTimeout</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">6000</span><span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">//10 Minutes</span>
sbc<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteToServer</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> CSVDataReader<span style="color: #008000;">&#40;</span>myFileName<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></pre></div></div>

<p>Of course, this relies on all of MyTable&#8217;s columns being of type varchar and the column headers in the CSV file need to match up with the column headers in the table, but this is supposed to be a simple spike.<br />
The first time I ran this, it was using about 12MB of memory for a 12MB file (my original 330K line file), and while this was an improvement over the 100s of MB for building the DataTable, it didn&#8217;t really tell me anything about how it might scale. So, I generated a file with about 35 million rows in it just to see what would happen. I was pleasantly surprised to find that it only used about 12MB from start to finish &#8211; this is clearly the benefit of using this DataReader model, the whole file/data structure is never in memory so we&#8217;re not generating enormous data structures to pass around.</p>
<p>If I have to do something similar to this in the future, I&#8217;ll probably tidy up this CSVDataReader and use it again. I may even implement the rest of it&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adhocgeek.com/2009/08/playing-with-idatareader-and-sqlbulkcopy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

