tag:blogger.com,1999:blog-28113080286566239662024-02-06T21:38:59.892-05:00Pragmatic SoftwareSeeking a pragmatic approach to software development blending proven designs with real-world constraints.Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.comBlogger127125tag:blogger.com,1999:blog-2811308028656623966.post-69424343389713195522017-12-16T09:19:00.002-05:002017-12-16T09:19:15.751-05:00This blog has moved...<div dir="ltr" style="text-align: left;" trbidi="on">
I'm now posting and exploring using GitHub and Jekyll at <a href="http://blog.pragmatictech.guru/">Pragmatic Technology</a></div>
Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-17456365684802867782014-06-19T08:58:00.000-04:002014-06-19T08:58:07.980-04:00Puppet Monitoring and Reporting<div dir="ltr" style="text-align: left;" trbidi="on">
I just received my review copy of <a href="http://bit.ly/1qbSxKC">Puppet Monitoring and Reporting</a> - timely given we're at the stage of deploying into production at work. A chance to put the book through its paces and see if it helps us.</div>
Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-33476970478216060082012-08-20T21:06:00.001-04:002012-08-20T21:08:26.183-04:00Is NuGet the nu DLL hell?<div dir="ltr" style="text-align: left;" trbidi="on">
At first I suspected this but after this weekend I'm convinced we're not off the hook. With the RTM release of VS 2012 I decided to try upgrading my <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">Simple Circles</a> project to see how things turned out. VS 2012 was okay - I had played with the RC version a bit - however, the various NuGet packages that had been upgraded since May when I last worked on it were numerous so I started slogging through them.<br />
<br />
Several packages had no dependencies and things generally went well. However, the combination of <a href="http://nuget.org/packages/NHibernate">NHibernate</a>, <a href="http://nuget.org/packages/FluentNHibernate">Fluent NHibernate</a>, <a href="http://nuget.org/packages/NHibernate.Logging">NHibernate Logging</a>, <a href="http://nuget.org/packages/Common.Logging">Common Logging</a>, and <a href="http://nuget.org/packages/Common.Logging.Log4Net">Common.Logging.Log4Net</a> (esp. 2.0 which is really 1.2.11 - that's another story) proved too much to bother with. After bumping each of the packages to current versions and checking dependencies my NHibernate unit tests all failed with configuration errors as well as object not found problems.<br />
<br />
Don't get me wrong - I like and believe in NuGet as a system and approach. However, it's not a panacea and it doesn't prevent compatibility problems even when so called "dependencies" are met. You still have to test the combinations of software you're using. In my case, I simply reverted to the earlier backup and voila - problems went away. I did take a few minutes of carefully upgrading the packages that weren't related, e.g. jQuery, AutoMapper, etc. while testing each upgrade to ensure nothing broke (hooray for unit tests!). I'll save the gnarly knot of remaining packages for another day when I have more time to unravel the problem.</div>
Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com1tag:blogger.com,1999:blog-2811308028656623966.post-6288741356686210712012-05-02T22:54:00.000-04:002012-05-02T22:54:24.759-04:00Turbo Pascal 6 circa 1992<div dir="ltr" style="text-align: left;" trbidi="on">
Found this old sample program written in Turbo Pascal 6. My recollection is that it would process a file received from a factory in Italy and print a report. Notice the first line of code for declaring the amount of memory? Umm…those are BYTES in the first line, as in minimum of 8K, maximum of 384K<br />
<br />
<pre><span style="color: green;"><i>{$M 8192, 0, 384000}</i></span>
<span style="color: green;"><i>{************************************************************
Program: ITALYSUM
Purpose: Print a list of styles with a summary by style
Author : John H. Watson III
Compile: Borland Turbo Pascal 6.0
Changed: 11/09/92 John Watson
Use extended syntax on WriteLn to format numeric
output right-adjusted. (e.g. "PairsNum:5"
instead of just "PairsNum").
Changed: 11/15/92 John Watson
Added style description to detail & summary print.
Removed hardcoding of field lengths in ProcessData
and replaced with constants.
Replaced hardcoded page titles with constants.
Change test of result of collection from "> 0"
to "<> -1". Zero is a valid location in the
collection and IndexOf will return a -1 if the
search doesn't find anything.
************************************************************}</i></span>
<span style="color: red;"><b>PROGRAM</b></span> ITALYSUM<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>USES</b></span> Dos<span style="color: blue;"><b>,</b></span> Printer<span style="color: blue;"><b>,</b></span> Objects<span style="color: blue;"><b>,</b></span> StdPrint<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>CONST</b></span>
CopyrightText <span style="color: blue;">=</span> <span style="color: purple;">'Copyright (c) 1992 by John H. Watson III'</span><span style="color: blue;"><b>;</b></span>
DetailTitle <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span> <span style="color: blue;">=</span> <span style="color: purple;">'Italy Data File Listing - Detail'</span><span style="color: blue;"><b>;</b></span>
SummaryTitle <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span> <span style="color: blue;">=</span> <span style="color: purple;">'Italy Data File Listing - Summary'</span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>VAR</b></span>
CopyrightStr <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">40</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>CONST</b></span>
MaxLines <span style="color: blue;">=</span> <span style="color: brown;">60</span><span style="color: blue;"><b>;</b></span>
Pagesize <span style="color: blue;">=</span> <span style="color: brown;">66</span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{********************************************************************
Define Objects
********************************************************************}</i></span>
<span style="color: red;"><b>TYPE</b></span>
pSummary <span style="color: blue;">=</span> <span style="color: cyan;"><span style="color: blue;">^</span>TSummary</span><span style="color: blue;"><b>;</b></span>
TSummary <span style="color: blue;">=</span> <span style="color: red;"><b>OBJECT</b></span><span style="color: blue;"><b>(</b></span>TObject<span style="color: blue;"><b>)</b></span>
Pairs <span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span>
Style <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">10</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
SDesc <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">30</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>CONSTRUCTOR</b></span> Init<span style="color: blue;"><b>(</b></span>iPairs<span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span> iStyle<span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>;</b></span> iSDesc<span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> Print<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> Accumulate<span style="color: blue;"><b>(</b></span>iPairs<span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
PStyleSummary <span style="color: blue;">=</span> <span style="color: cyan;"><span style="color: blue;">^</span>TStyleSummary</span><span style="color: blue;"><b>;</b></span>
TStyleSummary <span style="color: blue;">=</span> <span style="color: red;"><b>OBJECT</b></span><span style="color: blue;"><b>(</b></span>TSortedCollection<span style="color: blue;"><b>)</b></span>
<span style="color: red;"><b>FUNCTION</b></span> KeyOf<span style="color: blue;"><b>(</b></span>Item<span style="color: blue;"><b>:</b></span> Pointer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>:</b></span> Pointer<span style="color: blue;"><b>;</b></span> VIRTUAL<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>FUNCTION</b></span> Compare<span style="color: blue;"><b>(</b></span>Key1<span style="color: blue;"><b>,</b></span> Key2<span style="color: blue;"><b>:</b></span> Pointer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span> VIRTUAL<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{********************************************************************
Global Variables
********************************************************************}</i></span>
<span style="color: red;"><b>VAR</b></span>
ErrorCode <span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span>
F <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>File</b></span><span style="color: blue;"><b>;</b></span>
GrandTotal <span style="color: blue;"><b>:</b></span> Longint<span style="color: blue;"><b>;</b></span>
Path <span style="color: blue;"><b>:</b></span> PathStr<span style="color: blue;"><b>;</b></span>
SummaryList <span style="color: blue;"><b>:</b></span> pStyleSummary<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ define global instance }</i></span>
<span style="color: red;"><b>VAR</b></span>
FTime <span style="color: blue;"><b>:</b></span> Longint<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ file time }</i></span>
FDT <span style="color: blue;"><b>:</b></span> DateTime<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ DOS' date/time record structure }</i></span>
<span style="color: green;"><i>{********************************************************************
TSummary Object Methods
********************************************************************}</i></span>
<span style="color: red;"><b>CONSTRUCTOR</b></span> TSummary<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Init<span style="color: blue;"><b>(</b></span>iPairs<span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span> iStyle<span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>;</b></span> iSDesc<span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
TObject<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Init<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ call ancestor's init first }</i></span>
Pairs <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> iPairs<span style="color: blue;"><b>;</b></span>
Style <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> iStyle<span style="color: blue;"><b>;</b></span>
SDesc <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> iSDesc<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> TSummary<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Accumulate<span style="color: blue;"><b>(</b></span>iPairs<span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
Pairs <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> Pairs <span style="color: blue;">+</span> iPairs<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> TSummary<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Print<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
WRITELN<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span>Pairs<span style="color: blue;"><b>:</b></span><span style="color: brown;">5</span><span style="color: blue;"><b>,</b></span> <span style="color: purple;">' '</span><span style="color: blue;"><b>,</b></span> Style<span style="color: blue;"><b>,</b></span> <span style="color: purple;">' '</span><span style="color: blue;"><b>,</b></span> SDesc<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{********************************************************************
TStyleSummary Methods
********************************************************************}</i></span>
<span style="color: green;"><i>{ Define the key field for the collection. Since KeyOf expects
a pointer and Style is a simple string we must use the "@"
(address of) operator to generate the address (pointer). If
Style was a pString, this would not be necessary. }</i></span>
<span style="color: red;"><b>FUNCTION</b></span> TStyleSummary<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>KeyOf<span style="color: blue;"><b>(</b></span>Item<span style="color: blue;"><b>:</b></span> Pointer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>:</b></span> Pointer<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
KeyOf <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> <span style="color: blue;">@</span>pSummary<span style="color: blue;"><b>(</b></span>Item<span style="color: blue;"><b>)</b></span><span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Style<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>FUNCTION</b></span> TStyleSummary<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Compare<span style="color: blue;"><b>(</b></span>Key1<span style="color: blue;"><b>,</b></span> Key2<span style="color: blue;"><b>:</b></span> Pointer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
<span style="color: red;"><b>IF</b></span> pString<span style="color: blue;"><b>(</b></span>Key1<span style="color: blue;"><b>)</b></span><span style="color: blue;">^</span> <span style="color: blue;">=</span> pString<span style="color: blue;"><b>(</b></span>Key2<span style="color: blue;"><b>)</b></span><span style="color: blue;">^</span> <span style="color: red;"><b>THEN</b></span>
Compare <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> <span style="color: brown;">0</span>
<span style="color: red;"><b>ELSE</b></span> <span style="color: red;"><b>IF</b></span> pString<span style="color: blue;"><b>(</b></span>Key1<span style="color: blue;"><b>)</b></span><span style="color: blue;">^</span> <span style="color: blue;"><</span> pString<span style="color: blue;"><b>(</b></span>Key2<span style="color: blue;"><b>)</b></span><span style="color: blue;">^</span> <span style="color: red;"><b>THEN</b></span>
Compare <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> <span style="color: blue;">-</span><span style="color: brown;">1</span>
<span style="color: red;"><b>ELSE</b></span>
Compare <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> <span style="color: blue;">+</span><span style="color: brown;">1</span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{********************************************************************
Miscellaneous Procedures and Functions
********************************************************************}</i></span>
<span style="color: red;"><b>FUNCTION</b></span> OpenFile<span style="color: blue;"><b>(</b></span><span style="color: red;"><b>VAR</b></span> F<span style="color: blue;"><b>:</b></span><span style="color: red;"><b>File</b></span><span style="color: blue;"><b>;</b></span> iName<span style="color: blue;"><b>:</b></span>PathStr<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>:</b></span> BOOLEAN<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
ASSIGN<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>,</b></span> iName<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{$I-}</i></span> RESET<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>,</b></span> <span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{$I+}</i></span>
OpenFile <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> IOResult <span style="color: blue;">=</span> <span style="color: brown;">0</span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span> <span style="color: green;"><i>{Open}</i></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> Initialize<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>VAR</b></span>
Dir <span style="color: blue;"><b>:</b></span> DirStr<span style="color: blue;"><b>;</b></span>
Name <span style="color: blue;"><b>:</b></span> NameStr<span style="color: blue;"><b>;</b></span>
Extn <span style="color: blue;"><b>:</b></span> ExtStr<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
CopyrightStr <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> CopyrightText<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>IF</b></span> ParamCount <span style="color: blue;">=</span> <span style="color: brown;">0</span>
<span style="color: red;"><b>THEN</b></span> Path <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> <span style="color: purple;">'ITALYDTA'</span>
<span style="color: red;"><b>ELSE</b></span> Path <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> ParamStr<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Path <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> FExpand<span style="color: blue;"><b>(</b></span>Path<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ expand into full path string }</i></span>
FSplit<span style="color: blue;"><b>(</b></span>Path<span style="color: blue;"><b>,</b></span> Dir<span style="color: blue;"><b>,</b></span> Name<span style="color: blue;"><b>,</b></span> Extn<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ split into components }</i></span>
<span style="color: red;"><b>IF</b></span> <span style="color: blue;"><b>(</b></span>Name <span style="color: blue;">=</span> <span style="color: purple;">''</span><span style="color: blue;"><b>)</b></span> <span style="color: red;"><b>OR</b></span> <span style="color: red;"><b>NOT</b></span> OpenFile<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>,</b></span> Path<span style="color: blue;"><b>)</b></span> <span style="color: red;"><b>THEN</b></span> <span style="color: red;"><b>BEGIN</b></span>
WRITELN<span style="color: blue;"><b>(</b></span><span style="color: purple;">'ERROR: File not found ('</span><span style="color: blue;"><b>,</b></span> Name<span style="color: blue;"><b>,</b></span> <span style="color: purple;">').'</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
HALT<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
GetFTime<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>,</b></span> FTime<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
UnpackTime<span style="color: blue;"><b>(</b></span>FTime<span style="color: blue;"><b>,</b></span> FDT<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
GrandTotal <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> <span style="color: brown;">0</span><span style="color: blue;"><b>;</b></span>
LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> PageSize<span style="color: blue;"><b>;</b></span>
SummaryList <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> New<span style="color: blue;"><b>(</b></span>pStyleSummary<span style="color: blue;"><b>,</b></span> Init<span style="color: blue;"><b>(</b></span><span style="color: brown;">200</span><span style="color: blue;"><b>,</b></span> <span style="color: brown;">50</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ create collection }</i></span>
<span style="color: red;"><b>END</b></span> <span style="color: green;"><i>{Initialize}</i></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> Terminate<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
Close<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Close<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Dispose<span style="color: blue;"><b>(</b></span>SummaryList<span style="color: blue;"><b>,</b></span> Done<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> PrintHeading<span style="color: blue;"><b>(</b></span>iTitle<span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
<span style="color: red;"><b>IF</b></span> <span style="color: red;"><b>NOT</b></span> FirstPrint <span style="color: red;"><b>THEN</b></span> EjectPage<span style="color: blue;"><b>;</b></span>
VerticalTab<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> iTitle<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
VerticalTab<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>IF</b></span> FirstPrint <span style="color: red;"><b>THEN</b></span> <span style="color: red;"><b>BEGIN</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> <span style="color: purple;">'File: '</span><span style="color: blue;"><b>,</b></span> Path<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> <span style="color: purple;">'Date: '</span><span style="color: blue;"><b>,</b></span>FDT<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Month<span style="color: blue;"><b>,</b></span><span style="color: purple;">'/'</span><span style="color: blue;"><b>,</b></span>FDT<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Day<span style="color: blue;"><b>,</b></span><span style="color: purple;">'/'</span><span style="color: blue;"><b>,</b></span>FDT<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Year<span style="color: blue;"><b>,</b></span>
<span style="color: purple;">' Time: '</span><span style="color: blue;"><b>,</b></span>FDT<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Hour<span style="color: blue;"><b>,</b></span><span style="color: purple;">':'</span><span style="color: blue;"><b>,</b></span>FDT<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Min<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
VerticalTab<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>IF</b></span> FirstPrint
<span style="color: red;"><b>THEN</b></span> LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> <span style="color: brown;">6</span>
<span style="color: red;"><b>ELSE</b></span> LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> LineCount <span style="color: blue;">+</span> <span style="color: brown;">3</span><span style="color: blue;"><b>;</b></span>
FirstPrint <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> False<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{ Use ForEach iterator to display Summary information }</i></span>
<span style="color: red;"><b>PROCEDURE</b></span> PrintSummary<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>PROCEDURE</b></span> PrintSummaryObject<span style="color: blue;"><b>(</b></span>p <span style="color: blue;"><b>:</b></span> pSummary<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> FAR<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
<span style="color: red;"><b>IF</b></span> LineCount <span style="color: blue;">></span><span style="color: blue;">=</span> MaxLines <span style="color: red;"><b>THEN</b></span> <span style="color: red;"><b>BEGIN</b></span>
PrintHeading<span style="color: blue;"><b>(</b></span>SummaryTitle<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> <span style="color: purple;">'Pairs Style Description'</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> <span style="color: purple;">'----- ---------- -----------'</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
VerticalTab<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> LineCount <span style="color: blue;">+</span> <span style="color: brown;">3</span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
p<span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Print<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ Call object's print method }</i></span>
GrandTotal <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> GrandTotal <span style="color: blue;">+</span> p<span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Pairs<span style="color: blue;"><b>;</b></span>
LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> LineCount <span style="color: blue;">+</span> <span style="color: brown;">1</span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> MaxLines<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ force initial headings to print }</i></span>
SummaryList<span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>ForEach<span style="color: blue;"><b>(</b></span><span style="color: blue;">@</span>PrintSummaryObject<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
VerticalTab<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> GrandTotal<span style="color: blue;"><b>:</b></span><span style="color: brown;">5</span><span style="color: blue;"><b>,</b></span> <span style="color: purple;">' Grand Total'</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
EjectPage<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{ This procedure will read enough bytes to fill a record buffer.
Since the record length exceeds 255 bytes, we cannot use ReadLn to
read a record. To overcome this, the file is processed as an untyped
file and BlockRead is used to fill the buffer. }</i></span>
<span style="color: red;"><b>PROCEDURE</b></span> ProcessData<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>CONST</b></span>
PairsPos <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">578</span><span style="color: blue;"><b>;</b></span> PairsLen <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">5</span><span style="color: blue;"><b>;</b></span>
OrdNoPos <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">2</span><span style="color: blue;"><b>;</b></span> OrdNoLen <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">9</span><span style="color: blue;"><b>;</b></span>
RegNoPos <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">131</span><span style="color: blue;"><b>;</b></span> RegNoLen <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">6</span><span style="color: blue;"><b>;</b></span>
SDescPos <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">588</span><span style="color: blue;"><b>;</b></span> SDescLen <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">30</span><span style="color: blue;"><b>;</b></span>
StylePos <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">313</span><span style="color: blue;"><b>;</b></span> StyleLen <span style="color: blue;"><b>:</b></span> Integer <span style="color: blue;">=</span> <span style="color: brown;">10</span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>VAR</b></span>
Buffer <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>ARRAY</b></span><span style="color: blue;"><b>[</b></span>1<span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>905<span style="color: blue;"><b>]</b></span> <span style="color: red;"><b>OF</b></span> Char<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ includes two extra bytes for CR/LF }</i></span>
BytesRead <span style="color: blue;"><b>:</b></span> Word<span style="color: blue;"><b>;</b></span>
Location <span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ location in collection of existing summary object }</i></span>
NewObj<span style="color: blue;"><b>,</b></span> OldObj <span style="color: blue;"><b>:</b></span> pSummary<span style="color: blue;"><b>;</b></span>
PairsNum <span style="color: blue;"><b>:</b></span> Integer<span style="color: blue;"><b>;</b></span>
PairsStr <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">5</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
OrdNo <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">9</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
RegNo <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">6</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
Style <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">10</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
SDesc <span style="color: blue;"><b>:</b></span> <span style="color: red;"><b>String</b></span><span style="color: blue;"><b>[</b></span><span style="color: brown;">30</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
BlockRead<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>,</b></span> Buffer<span style="color: blue;"><b>,</b></span> SizeOf<span style="color: blue;"><b>(</b></span>Buffer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>,</b></span> BytesRead<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>WHILE</b></span> <span style="color: blue;"><b>(</b></span><span style="color: red;"><b>NOT</b></span> EOF<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>)</b></span> <span style="color: red;"><b>DO</b></span> <span style="color: red;"><b>BEGIN</b></span>
<span style="color: green;"><i>{ Extract individual fields from record buffer }</i></span>
Move<span style="color: blue;"><b>(</b></span>Buffer<span style="color: blue;"><b>[</b></span>StylePos<span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> Style<span style="color: blue;"><b>[</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> StyleLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Style<span style="color: blue;"><b>[</b></span><span style="color: brown;">0</span><span style="color: blue;"><b>]</b></span> <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> Char<span style="color: blue;"><b>(</b></span>StyleLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ force the proper string size }</i></span>
Move<span style="color: blue;"><b>(</b></span>Buffer<span style="color: blue;"><b>[</b></span>SDescPos<span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> SDesc<span style="color: blue;"><b>[</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> SDescLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
SDesc<span style="color: blue;"><b>[</b></span><span style="color: brown;">0</span><span style="color: blue;"><b>]</b></span> <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> Char<span style="color: blue;"><b>(</b></span>SDescLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Move<span style="color: blue;"><b>(</b></span>Buffer<span style="color: blue;"><b>[</b></span>OrdNoPos<span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> OrdNo<span style="color: blue;"><b>[</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> OrdNoLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
OrdNo<span style="color: blue;"><b>[</b></span><span style="color: brown;">0</span><span style="color: blue;"><b>]</b></span> <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> Char<span style="color: blue;"><b>(</b></span>OrdNoLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Move<span style="color: blue;"><b>(</b></span>Buffer<span style="color: blue;"><b>[</b></span>RegNoPos<span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> RegNo<span style="color: blue;"><b>[</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> RegNoLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
RegNo<span style="color: blue;"><b>[</b></span><span style="color: brown;">0</span><span style="color: blue;"><b>]</b></span> <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> Char<span style="color: blue;"><b>(</b></span>RegNoLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Move<span style="color: blue;"><b>(</b></span>Buffer<span style="color: blue;"><b>[</b></span>PairsPos<span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> PairsStr<span style="color: blue;"><b>[</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>]</b></span><span style="color: blue;"><b>,</b></span> PairsLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
PairsStr<span style="color: blue;"><b>[</b></span><span style="color: brown;">0</span><span style="color: blue;"><b>]</b></span> <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> Char<span style="color: blue;"><b>(</b></span>PairsLen<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
Val<span style="color: blue;"><b>(</b></span>PairsStr<span style="color: blue;"><b>,</b></span> PairsNum<span style="color: blue;"><b>,</b></span> ErrorCode<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ convert string to numeric }</i></span>
<span style="color: green;"><i>{ Print detail line }</i></span>
<span style="color: red;"><b>IF</b></span> LineCount <span style="color: blue;">></span><span style="color: blue;">=</span> MaxLines <span style="color: red;"><b>THEN</b></span> <span style="color: red;"><b>BEGIN</b></span>
PrintHeading<span style="color: blue;"><b>(</b></span>DetailTitle<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> <span style="color: purple;">'Order No Reg No Pairs Style Description'</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
WriteLn<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> <span style="color: purple;">'--------- ------ ----- ---------- -----------'</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
VerticalTab<span style="color: blue;"><b>(</b></span><span style="color: brown;">1</span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> LineCount <span style="color: blue;">+</span> <span style="color: brown;">3</span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
WRITELN<span style="color: blue;"><b>(</b></span>LST<span style="color: blue;"><b>,</b></span> OrdNo<span style="color: blue;"><b>,</b></span> <span style="color: purple;">' '</span><span style="color: blue;"><b>,</b></span> RegNo<span style="color: blue;"><b>,</b></span> <span style="color: purple;">' '</span><span style="color: blue;"><b>,</b></span> PairsNum<span style="color: blue;"><b>:</b></span><span style="color: brown;">5</span><span style="color: blue;"><b>,</b></span> <span style="color: purple;">' '</span><span style="color: blue;"><b>,</b></span> Style<span style="color: blue;"><b>,</b></span> <span style="color: purple;">' '</span><span style="color: blue;"><b>,</b></span> SDesc<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
LineCount <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> LineCount <span style="color: blue;">+</span> <span style="color: brown;">1</span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{ Now create a new instance of a summary object with these values }</i></span>
NewObj <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> New<span style="color: blue;"><b>(</b></span>pSummary<span style="color: blue;"><b>,</b></span> Init<span style="color: blue;"><b>(</b></span>PairsNum<span style="color: blue;"><b>,</b></span> Style<span style="color: blue;"><b>,</b></span> SDesc<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: green;"><i>{ Search the collection to see if it already exists }</i></span>
Location <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> SummaryList<span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>IndexOf<span style="color: blue;"><b>(</b></span>NewObj<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>IF</b></span> Location <span style="color: blue;"><</span><span style="color: blue;">></span> <span style="color: blue;">-</span><span style="color: brown;">1</span> <span style="color: red;"><b>THEN</b></span> <span style="color: red;"><b>BEGIN</b></span> <span style="color: green;"><i>{ If found, accumulate pairs }</i></span>
OldObj <span style="color: blue;"><b>:</b></span><span style="color: blue;">=</span> SummaryList<span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>AT<span style="color: blue;"><b>(</b></span>Location<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ get ptr to obj @ location }</i></span>
OldObj<span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Accumulate<span style="color: blue;"><b>(</b></span>PairsNum<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ call that obj's accumulate method }</i></span>
<span style="color: red;"><b>END</b></span>
<span style="color: red;"><b>ELSE</b></span> SummaryList<span style="color: blue;">^</span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span>Insert<span style="color: blue;"><b>(</b></span>NewObj<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span> <span style="color: green;"><i>{ else add to collection }</i></span>
BlockRead<span style="color: blue;"><b>(</b></span>F<span style="color: blue;"><b>,</b></span> Buffer<span style="color: blue;"><b>,</b></span> SizeOf<span style="color: blue;"><b>(</b></span>Buffer<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>,</b></span> BytesRead<span style="color: blue;"><b>)</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span> <span style="color: green;"><i>{ProcessData}</i></span><span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>BEGIN</b></span>
Initialize<span style="color: blue;"><b>;</b></span>
ProcessData<span style="color: blue;"><b>;</b></span>
PrintSummary<span style="color: blue;"><b>;</b></span>
Terminate<span style="color: blue;"><b>;</b></span>
<span style="color: red;"><b>END</b></span><span style="color: blue;"><b><span style="color: blue;"><b>.</b></span></b></span></pre>
</div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-11599400681494100482012-05-02T22:52:00.004-04:002012-05-02T22:52:50.545-04:00Printing 1099’s in Cobol, circa 1991<div dir="ltr" style="text-align: left;" trbidi="on">
20 years ago, this is how we printed 1099’s…Many liked to call Cobol “wordy” but it was more accurate to say “self documenting”:<br />
<br />
MOVE YTD-FED-GROSS-FINAL TO DATA-2 IN LINE-1. <br />
WRITE PRINT-RECORD FROM LINE-1 BEFORE ADVANCING 6. <br />
<br />
“Look Mom, no need for comments”:<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="color: #e34adc;">IDENTIFICATION DIVISION.</span>
<span style="color: #004a43;">PROGRAM-ID</span><span style="color: maroon; font-weight: bold;">.</span> PRR1099<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> PRINT PAYROLL </span><span style="color: #008c00;">1099</span><span style="color: dimgrey;"> FORMS</span>
<span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: #008c00;">11</span><span style="color: maroon; font-weight: bold;">/</span><span style="color: #008c00;">25</span><span style="color: maroon; font-weight: bold;">/</span><span style="color: #008c00;">91</span><span style="color: dimgrey;"> JOHN WATSON </span><span style="color: maroon; font-weight: bold;">-</span><span style="color: dimgrey;"> </span><span style="color: dimgrey;">CREATED</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> HEADER <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">SPECIAL-NAMES</span><span style="color: maroon; font-weight: bold;">.</span> <span style="color: #0000e6;">LOCAL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">DATA</span> <span style="color: maroon; font-weight: bold;">IS</span> WS<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #004a43;">INPUT-OUTPUT</span> <span style="color: #004a43;">SECTION</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #004a43;">FILE-CONTROL</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> ADM1SL <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">SELECT</span> EMPLFILE <span style="color: maroon; font-weight: bold;">ASSIGN</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">DATABASE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">PRCYTDPF</span>
<span style="color: maroon; font-weight: bold;">ORGANIZATION</span> <span style="color: maroon; font-weight: bold;">IS</span> <span style="color: maroon; font-weight: bold;">SEQUENTIAL</span>
<span style="color: maroon; font-weight: bold;">ACCESS</span> <span style="color: maroon; font-weight: bold;">MODE</span> <span style="color: maroon; font-weight: bold;">IS</span> <span style="color: maroon; font-weight: bold;">SEQUENTIAL</span>
<span style="color: #004a43;">FILE</span> <span style="color: maroon; font-weight: bold;">STATUS</span> <span style="color: maroon; font-weight: bold;">IS</span> <span style="color: #0000e6;">IO</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">STATUS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">SELECT</span> SCRNFILE <span style="color: maroon; font-weight: bold;">ASSIGN</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">WORKSTATION</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">PRRPTSSC-SI</span>
<span style="color: maroon; font-weight: bold;">ORGANIZATION</span> <span style="color: maroon; font-weight: bold;">IS</span> TRANSACTION<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">SELECT</span> PRNTFILE <span style="color: maroon; font-weight: bold;">ASSIGN</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">PRINTER</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">TRCSPRTF</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #004a43;">DATA</span> <span style="color: #004a43;">DIVISION</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #004a43;">FILE</span> <span style="color: #004a43;">SECTION</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> SCRNFD <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> PRNTFD <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">FD</span> ADM1FILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: #0000e6;">ADM1</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">REC</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> <span style="color: #0000e6;">DD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ADM1DATA</span> <span style="color: maroon; font-weight: bold;">OF</span> ADM1FILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">FD</span> EMPLFILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: #0000e6;">EMPL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">REC</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> <span style="color: #0000e6;">DD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">EMPLDATA</span> <span style="color: maroon; font-weight: bold;">OF</span> PRCYTDPF<span style="color: maroon; font-weight: bold;">.</span>
EJECT<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #004a43;">WORKING-STORAGE</span> <span style="color: #004a43;">SECTION</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">77</span> X <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: #008c00;">999</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">77</span> LIMITER <span style="color: maroon; font-weight: bold;">PIC</span> X <span style="color: maroon; font-weight: bold;">VALUE</span> <span style="color: #0000e6;">"*"</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: #004a43;">FILE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">STATUS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">ADM1FILE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">STATUS</span> <span style="color: maroon; font-weight: bold;">PIC</span> XX<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">IO</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">STATUS</span> <span style="color: maroon; font-weight: bold;">PIC</span> XX<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">PROGRAM</span><span style="color: maroon; font-weight: bold;">-</span>FLAGS<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">END</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #004a43;">FILE</span><span style="color: maroon; font-weight: bold;">-</span>FLAG <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: #008c00;">9</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">PROGRAM</span><span style="color: maroon; font-weight: bold;">-</span>COUNTERS<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #008c00;">1099</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">COUNT</span> <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: #008c00;">9</span><span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">5</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">FORM</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">COUNT</span> <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: #008c00;">9</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">FINAL</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #0000e6;">TOTAL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FIELDS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">STATE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">GROSS-FINAL</span> <span style="color: maroon; font-weight: bold;">PIC</span> S9<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">8</span><span style="color: maroon; font-weight: bold;">)</span>V99 <span style="color: maroon; font-weight: bold;">COMP</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">FED</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">GROSS-FINAL</span> <span style="color: maroon; font-weight: bold;">PIC</span> S9<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">8</span><span style="color: maroon; font-weight: bold;">)</span>V99 <span style="color: maroon; font-weight: bold;">COMP</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">STATE-TAX-FINAL</span> <span style="color: maroon; font-weight: bold;">PIC</span> S9<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">8</span><span style="color: maroon; font-weight: bold;">)</span>V99 <span style="color: maroon; font-weight: bold;">COMP</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FED-TAX-FINAL</span> <span style="color: maroon; font-weight: bold;">PIC</span> S9<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">8</span><span style="color: maroon; font-weight: bold;">)</span>V99 <span style="color: maroon; font-weight: bold;">COMP</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">ERROR</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">MESSAGE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">LINES</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">CONFIRM</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">SCREEN-MESSAGE</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">05</span> <span style="color: #0000e6;">CONFIRM</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">SCREEN-MESSAGE-1</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">49</span><span style="color: maroon; font-weight: bold;">)</span> <span style="color: maroon; font-weight: bold;">VALUE</span> <span style="color: maroon; font-weight: bold;">SPACES</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">05</span> <span style="color: #0000e6;">CONFIRM</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">SCREEN-MESSAGE-2</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">21</span><span style="color: maroon; font-weight: bold;">)</span> <span style="color: maroon; font-weight: bold;">VALUE</span>
<span style="color: #0000e6;">"CONFIRM DATA ENTERED."</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> ZBEGINDD <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">RECORD</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">IN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">PAGE1</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">IN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> <span style="color: #0000e6;">DD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">W2S01</span> <span style="color: maroon; font-weight: bold;">OF</span> PRRPTSSC<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">ERROR</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">IN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #0000e6;">PAGEERROR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">IN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> <span style="color: #0000e6;">DD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ERRORSCR</span> <span style="color: maroon; font-weight: bold;">OF</span> PRRPTSSC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> XPRNTDD <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">6</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">32</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: green;">9.99</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: green;">9.99</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">6</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">32</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">12</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">13</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">6</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">15</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">15</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: green;">9.99</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">4</span> <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: green;">9.99</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">4</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">6</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">32</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">9</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">01</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">5</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">6</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">32</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">PIC</span> <span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: green;">9.99</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #008c00;">03</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">PIC</span> X<span style="color: maroon; font-weight: bold;">(</span><span style="color: #008c00;">13</span><span style="color: maroon; font-weight: bold;">)</span><span style="color: maroon; font-weight: bold;">.</span>
EJECT<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #004a43;">PROCEDURE</span> <span style="color: #004a43;">DIVISION</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">DECLARATIVES</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> ADM1ERR <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #0000e6;">EMPLFILE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ERROR</span> <span style="color: #004a43;">SECTION</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">USE</span> <span style="color: maroon; font-weight: bold;">AFTER</span> <span style="color: maroon; font-weight: bold;">ERROR</span> <span style="color: #004a43;">PROCEDURE</span> <span style="color: maroon; font-weight: bold;">ON</span> EMPLFILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #0000e6;">EMPLFILE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">DECL</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">"EMPL"</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">ERROR</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #004a43;">FILE</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">IO</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">STATUS</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">ERROR</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">CODE</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #004a43;">FILE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">ERROR</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">MESSAGE</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">ERROR</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: #0000e6;">ERRORSCR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">O</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: #0000e6;">PAGEERROR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">IN</span> FORMAT <span style="color: #0000e6;">"ERRORSCR"</span>
INDICATORS <span style="color: maroon; font-weight: bold;">ARE</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span>INDICATORS
<span style="color: maroon; font-weight: bold;">READ</span> SCRNFILE <span style="color: maroon; font-weight: bold;">RECORD</span> <span style="color: maroon; font-weight: bold;">INTO</span> <span style="color: #0000e6;">PAGEERROR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">IN</span> FORMAT <span style="color: #0000e6;">"ERRORSCR"</span>
INDICATORS <span style="color: maroon; font-weight: bold;">ARE</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span>INDICATORS
<span style="color: maroon; font-weight: bold;">STOP</span> <span style="color: maroon; font-weight: bold;">RUN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">END</span> <span style="color: maroon; font-weight: bold;">DECLARATIVES</span><span style="color: maroon; font-weight: bold;">.</span>
EJECT<span style="color: maroon; font-weight: bold;">.</span>
MAIN <span style="color: #004a43;">SECTION</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #0000e6;">CLEAR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">SCREEN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">"PRR1099 - 1099 FORMS"</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">PROGRAM</span><span style="color: maroon; font-weight: bold;">-</span>NAME <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: #0000e6;">ERRORSCR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">O</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">OPEN</span> <span style="color: maroon; font-weight: bold;">I-O</span> SCRNFILE
<span style="color: maroon; font-weight: bold;">INPUT</span> ADM1FILE<span style="color: maroon; font-weight: bold;">,</span> EMPLFILE
<span style="color: maroon; font-weight: bold;">OUTPUT</span> PRNTFILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">COPY</span> ZBEGIN <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">PROGRAM</span><span style="color: maroon; font-weight: bold;">-</span>FLAGS<span style="color: maroon; font-weight: bold;">,</span> <span style="color: maroon; font-weight: bold;">PROGRAM</span><span style="color: maroon; font-weight: bold;">-</span>COUNTERS<span style="color: maroon; font-weight: bold;">,</span>
<span style="color: maroon; font-weight: bold;">FINAL</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #0000e6;">TOTAL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FIELDS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">READ</span> ADM1FILE <span style="color: maroon; font-weight: bold;">RECORD</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">SET</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">UP</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: maroon; font-weight: bold;">SPACES</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">RECORD</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">IN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: #0000e6;">W2S01</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">O</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">START</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #0000e6;">W2</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">NO</span> <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: #0000e6;">W2S01</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">I</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">ACCEPT</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: #0000e6;">PAGE1</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">IN</span> FORMAT <span style="color: #0000e6;">"W2S01"</span>
INDICATORS <span style="color: maroon; font-weight: bold;">ARE</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span>INDICATORS<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">READ</span> SCRNFILE <span style="color: maroon; font-weight: bold;">RECORD</span> <span style="color: maroon; font-weight: bold;">INTO</span> <span style="color: #0000e6;">PAGE1</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">IN</span> FORMAT <span style="color: #0000e6;">"W2S01"</span>
INDICATORS <span style="color: maroon; font-weight: bold;">ARE</span> <span style="color: maroon; font-weight: bold;">SCREEN</span><span style="color: maroon; font-weight: bold;">-</span>INDICATORS<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">IF</span> <span style="color: #0000e6;">SCR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">IND(93)</span> <span style="color: maroon; font-weight: bold;">=</span> B<span style="color: #0000e6;">"1"</span>
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">END</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">PROGRAM</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">IF</span> <span style="color: maroon; font-weight: bold;">START</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #0000e6;">W2</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">NO</span> <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: #0000e6;">W2S01</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">I</span> <span style="color: maroon; font-weight: bold;">=</span> <span style="color: maroon; font-weight: bold;">ZERO</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">"INVALID CONTROL NUMBER. RE-ENTER."</span>
<span style="color: maroon; font-weight: bold;">TO</span> ERRLINE <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: #0000e6;">W2S01</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">I</span>
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">ACCEPT</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
EJECT<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">READ</span><span style="color: maroon; font-weight: bold;">-</span>EMPLFILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">READ</span> EMPLFILE <span style="color: maroon; font-weight: bold;">NEXT</span> <span style="color: maroon; font-weight: bold;">RECORD</span>
<span style="color: maroon; font-weight: bold;">AT</span> <span style="color: maroon; font-weight: bold;">END</span> <span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">END</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #004a43;">FILE</span><span style="color: maroon; font-weight: bold;">-</span>FLAG
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">CHECK</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">SUBTOT-FLAG</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #0000e6;">CHECK</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">START-1099-NO</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #008c00;">0</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">SUBTOT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FLAG</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">ADD</span> <span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #008c00;">1099</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">COUNT</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">IF</span> <span style="color: maroon; font-weight: bold;">START</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #0000e6;">W2</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">NO</span> <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: #0000e6;">W2S01</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">I</span> <span style="color: maroon; font-weight: bold;">GREATER</span> <span style="color: maroon; font-weight: bold;">THAN</span> <span style="color: #008c00;">1099</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">COUNT</span>
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">ACCUM</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #0000e6;">CHECK</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FIRST-PRINTING</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">IF</span> <span style="color: maroon; font-weight: bold;">FIRST</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">PRINTING</span> <span style="color: maroon; font-weight: bold;">=</span> <span style="color: #008c00;">1</span>
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">MOVE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">BLANK</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">LINE</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">5</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">FIRST</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">PRINTING</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">SCHOOL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">NAME</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-FED-GROSS</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">SCHOOL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ADDR-1</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">SCHOOL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ADDR-2</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">SCHOOL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ADDR-3</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-FED-GROSS</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">6</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">FEDERAL</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ID</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">SOC</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">SEC-NO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-FED-TAX</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">4</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FULL-NAME</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">ADDR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">LINE-1</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">ADDR</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">LINE-2</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INSPECT</span> CITY <span style="color: maroon; font-weight: bold;">REPLACING</span> <span style="color: maroon; font-weight: bold;">ALL</span> <span style="color: #0000e6;">" "</span> <span style="color: maroon; font-weight: bold;">BY</span> <span style="color: #0000e6;">"**"</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">STRING</span> CITY <span style="color: maroon; font-weight: bold;">DELIMITED</span> <span style="color: maroon; font-weight: bold;">BY</span> LIMITER <span style="color: maroon; font-weight: bold;">SPACE</span> <span style="color: maroon; font-weight: bold;">SPACE</span>
<span style="color: #0000e6;">STATE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">CODE</span> <span style="color: maroon; font-weight: bold;">DELIMITED</span> <span style="color: maroon; font-weight: bold;">BY</span> LIMITER <span style="color: maroon; font-weight: bold;">SPACE</span>
<span style="color: #0000e6;">ZIP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">CODE</span> <span style="color: maroon; font-weight: bold;">DELIMITED</span> <span style="color: maroon; font-weight: bold;">BY</span> LIMITER
<span style="color: maroon; font-weight: bold;">INTO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">5</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-STATE-TAX</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">5</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">STATE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">ID</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">5</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">5</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: maroon; font-weight: bold;">PAGE</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #0000e6;">ACCUM</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">TOTALS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">ADD</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-FED-TAX</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FED-TAX-FINAL</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">ADD</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-FED-GROSS</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">FED</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">GROSS-FINAL</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">ADD</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-STATE-TAX</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">STATE-TAX-FINAL</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">ADD</span> <span style="color: #0000e6;">EMP</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">YTD-STATE-GROSS</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">STATE</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">GROSS-FINAL</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: #0000e6;">CHECK</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">END-FILE-FLAG</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">IF</span> <span style="color: maroon; font-weight: bold;">END</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #004a43;">FILE</span><span style="color: maroon; font-weight: bold;">-</span>FLAG <span style="color: maroon; font-weight: bold;">=</span> <span style="color: #008c00;">1</span>
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FINAL-TOTALS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">IF</span> <span style="color: maroon; font-weight: bold;">START</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #0000e6;">W2</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">NO</span> <span style="color: maroon; font-weight: bold;">OF</span> <span style="color: #0000e6;">W2S01</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">I</span> <span style="color: maroon; font-weight: bold;">GREATER</span> <span style="color: maroon; font-weight: bold;">THAN</span> <span style="color: #008c00;">1099</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">COUNT</span>
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">READ</span><span style="color: maroon; font-weight: bold;">-</span>EMPLFILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">GO</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: maroon; font-weight: bold;">READ</span><span style="color: maroon; font-weight: bold;">-</span>EMPLFILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">FINAL</span><span style="color: dimgrey;"> SUBTOTALS </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> </span><span style="color: maroon; font-weight: bold;">*</span>
<span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FINAL-TOTALS</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">BLANK</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">LINE</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">5</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">" FINAL TOTALS"</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FED-GROSS-FINAL</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">3</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FED-GROSS-FINAL</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">6</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">FED-TAX-FINAL</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">4</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">2</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">12</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">INITIALIZE</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">MOVE</span> <span style="color: #0000e6;">YTD</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">STATE-TAX-FINAL</span> <span style="color: maroon; font-weight: bold;">TO</span> <span style="color: #004a43;">DATA</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">3</span> <span style="color: maroon; font-weight: bold;">IN</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">WRITE</span> <span style="color: #0000e6;">PRINT</span><span style="color: #0000e6;">-</span><span style="color: #0000e6;">RECORD</span> <span style="color: maroon; font-weight: bold;">FROM</span> <span style="color: maroon; font-weight: bold;">LINE</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: #008c00;">1</span> <span style="color: maroon; font-weight: bold;">BEFORE</span> <span style="color: maroon; font-weight: bold;">ADVANCING</span> <span style="color: #008c00;">1</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">END</span><span style="color: maroon; font-weight: bold;">-</span><span style="color: maroon; font-weight: bold;">PROGRAM</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">CLOSE</span> ADM1FILE<span style="color: maroon; font-weight: bold;">,</span> EMPLFILE<span style="color: maroon; font-weight: bold;">,</span> PRNTFILE<span style="color: maroon; font-weight: bold;">,</span> SCRNFILE<span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">STOP</span> <span style="color: maroon; font-weight: bold;">RUN</span><span style="color: maroon; font-weight: bold;">.</span>
<span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: dimgrey;"> R O U T I N E S </span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span><span style="color: maroon; font-weight: bold;">*</span>
<span style="color: maroon; font-weight: bold;">COPY</span> XDATE <span style="color: maroon; font-weight: bold;">OF</span> CBLCPYSRC <span style="color: maroon; font-weight: bold;">SUPPRESS</span><span style="color: maroon; font-weight: bold;">.</span></pre>
</div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-75469669376892089112012-05-02T22:51:00.001-04:002012-05-02T22:51:30.456-04:00Extracting MSDS Finished Goods from MAPICS/38 using PL/1<div dir="ltr" style="text-align: left;" trbidi="on">
Okay, this has to take the cake for a rare combination…a PL/1 program that walks down an assembly chain for a finished good product and explodes out the complete list of raw materials that make up the product. I had to build a “shadow” bill of materials for each finished good item that consisted of the raw materials so I could then simulate chemical reactions and determine the remaining ingredients that where left. If these ingredients were then above certain thresholds they have to be declared on a Material Safety Data Sheet. Wonder how it might look in C# in an OO style using today’s patterns?<br />
<br />
<pre>/* MSD710P - Load a Product Structure into MSDS from PDM */
MSD710P: PROCEDURE (BR_ITEM_IN) RETURNS(CHAR(2));
/********************************************************************/
/* NAME: MSD710P */
/* PURPOSE: Load the Mapics/38 Product Structure into MSDS System */
/* WRITTEN: 01/30/90 */
/* AUTHOR: John Watson */
/* SYSTEM: IBM System/38 */
/* LANGUAGE: PL/I */
/* SECURITY: None */
/* DESCR: This pgm extracts the product structure of an item */
/* from the Mapics/38 Product Structure file (PSTRUC) */
/* and builds the MSDS Finished Good/Component file */
/* (COMPNT). Only final raw materials are output to the */
/* MSDS system. That is, phantoms and sub-assemblies are */
/* exploded down to their raw materials as well. The raw */
/* material quantities are converted to pounds or gallons */
/* in a batch size of 100 (100 lbs / 100 gals) for the */
/* 100 Unit Formula used by the MSDS system. */
/* NOTE: This is designed as a function to */
/* FACILITATe returning to the caller */
/* with return codes. */
/* */
/* RETURN: 00 = Successful completion */
/* 1x = Problem w/ finished good item */
/* 0 = Item A record not found */
/* 1 = Deleted Item A */
/* 2 = Assembly chain not found */
/* 2x = Problem w/ a component */
/* 0 = PSTRUC not found, assy chain broken/bad */
/* 1 = component Item A record not found */
/* 2 = RRNs don't match */
/* 3 = component Item A deleted */
/* 4 = compare portions don't match */
/* 5 = bad low level code (exceeds 99) */
/* 6 = MSFILM record not found - cannot convert qty */
/* */
/********************************************************************/
/* DECLARE FILES */
DCL
ITEMAKEY FILE RECORD INPUT DIRECT KEYED INTERNAL
ENV(BUFSIZE(256) INDEXED KEYDISP(1) KEYLENGTH(16)),
ITEMARRN FILE RECORD INPUT DIRECT ENV(BUFSIZE(256)) INTERNAL,
ITEMAC FILE RECORD INPUT DIRECT KEYED ENV(DESCRIBED INDEXED),
PSTRUC FILE RECORD INPUT DIRECT ENV(BUFSIZE(96)) INTERNAL,
MSFILMPF FILE RECORD INPUT DIRECT KEYED ENV(DESCRIBED INDEXED),
MSBSRMPF FILE RECORD SEQUENTIAL KEYED ENV(DESCRIBED INDEXED);
/* DECLARE RECORDS FOR INPUT FROM FILES */
DCL 1 COMPNT,
%INCLUDE MSBSRMPF(COMPNT,RECORD);
DCL 1 CFMT,
%INCLUDE ITEMAC(CFMT,RECORD);
DCL 1 RMFILM,
%INCLUDE MSFILMPF(RMFILM,RECORD);
/**************************************************/
/* ITEMAS is internally described because we need */
/* std batch qty of parent from pos. 244-249. */
/**************************************************/
DCL 1 ITEMA_P,
2 PR_ACREC CHAR(1), /* active record code */
2 PR_ITNBR CHAR(15), /* item number */
2 PR_FILL1 CHAR(1), /* filler 1 */
2 PR_IIREC DEC(7,0), /* RRN for this item */
2 PR_LOLEV PIC '9R', /* low level code */
2 PR_IIFAC DEC(7,0), /* RRN of first assembly component */
2 PR_FILL2 CHAR(105), /* filler 2 */
2 PR_UNMSR CHAR(2), /* unit of measure */
2 PR_ITTYP CHAR(1), /* item type */
2 PR_FILL3 CHAR(108), /* filler 3 */
2 PR_SBQTY DEC(11,3), /* standard batch quantity */
2 PR_FILL4 CHAR(7); /* filler 4 */
DCL 1 ITEMA_C,
2 PC_ACREC CHAR(1), /* active record code */
2 PC_ITNBR CHAR(15), /* item number */
2 PC_FILL1 CHAR(1), /* filler 1 */
2 PC_IIREC DEC(7,0), /* RRN for this item */
2 PC_LOLEV PIC '9R', /* low level code */
2 PC_IIFAC DEC(7,0), /* RRN of first assembly component */
2 PC_FILL2 CHAR(105), /* filler 2 */
2 PC_UNMSR CHAR(2), /* unit of measure */
2 PC_ITTYP CHAR(1), /* item type */
2 PC_FILL3 CHAR(108), /* filler 3 */
2 PC_SBQTY DEC(11,3), /* standard batch quantity */
2 PC_FILL4 CHAR(7); /* filler 4 */
DCL 1 PSTRUCT,
2 PPCIM DEC(7,0), /* component item A RRN */
2 PPPIM DEC(7,0), /* parent item "A" RRN */
2 PPNAC DEC(7,0), /* next assembly component RRN */
2 PPFIL1 CHAR(8), /* filler 1 */
2 CCMPI CHAR(1), /* compare portion of item number */
2 PCOMP CHAR(1), /* compare portion of parent item */
2 PPFIL2 CHAR(16), /* filler 2 */
2 EDATM DEC(6,0), /* effective from date */
2 EDATO DEC(6,0), /* effective to date */
2 PPFIL3 CHAR(44), /* filler 3 */
2 QTYPR DEC(11,3); /* quantity per unit */
/* DECLARE VARIABLES */
DCL BATCH_SZ DEC(7,3), /* batch size */
CMP(100) CHAR(1), /* compare characters */
CMP_CHAR CHAR(1), /* compare character */
CNTRL_ID CHAR(3), /* used to redefine PPCIM */
BR_ITEM_IN CHAR(6),
LVL DEC(3,0), /* array subscript */
STD_BAT_QTY DEC(11,3),
RRN(100) DEC(7,0), /* RRNs to chase down assy chains */
REC_NO DEC(7,0), /* RRN workfield */
SBQ(100) DEC(11,3), /* Std batch qty for a given level */
WRK_QTY FLOAT(7);
/* SYSTEM DATE */
DCL CHR_DATE CHAR(6),
TST_DATE DEC(6,0); /* YYMMDD */
DCL 1 PROGRAM_FLAGS STATIC,
2 NO BIT(1) ALIGNED INIT('0'B),
2 YES BIT(1) ALIGNED INIT('1'B),
2 VALID_ITEM_A BIT(1) ALIGNED,
2 VALID_ITEM_C BIT(1) ALIGNED,
2 VALID_PSTRUC BIT(1) ALIGNED,
2 VALID_RMFILM BIT(1) ALIGNED,
2 MORE_COMPNT_RECS BIT(1) ALIGNED;
/* OPEN FILES */
OPEN FILE(ITEMAKEY);
OPEN FILE(ITEMARRN);
OPEN FILE(ITEMAC);
OPEN FILE(MSFILMPF);
OPEN FILE(PSTRUC);
/* ERROR HANDLING */
ON KEY(ITEMAKEY) VALID_ITEM_A=NO;
ON KEY(ITEMARRN) VALID_ITEM_A=NO;
ON KEY(ITEMAC) VALID_ITEM_C=NO;
ON KEY(PSTRUC) VALID_PSTRUC=NO;
ON KEY(MSFILMPF) VALID_RMFILM=NO;
ON KEY(MSBSRMPF) MORE_COMPNT_RECS=NO;
ON ENDFILE(MSBSRMPF) MORE_COMPNT_RECS=NO;
%PAGE;
/* M A I N L I N E */
CHR_DATE=DATE();
TST_DATE=DECIMAL(CHR_DATE,6,0);
BATCH_SZ=100;
LVL=1;
RRN=0;
SBQ=0;
CMP=' ';
/* Get parent Item A */
VALID_ITEM_A=YES;
READ FILE(ITEMAKEY) INTO(ITEMA_P) KEY(BR_ITEM_IN);
SELECT;
WHEN (VALID_ITEM_A=NO) RETURN('10'); /* record not found */
WHEN (PR_ACREC='D') RETURN('11'); /* deleted record */
WHEN (PR_IIFAC=9999999) RETURN('12'); /* no assembly chain */
OTHERWISE;
END;
REC_NO=PR_IIFAC;
STD_BAT_QTY=PR_SBQTY;
CMP_CHAR=SUBSTR(PR_ITNBR,1,1);
/* Clear out old COMPNT records */
OPEN FILE(MSBSRMPF) UPDATE;
MORE_COMPNT_RECS=YES;
READ FILE(MSBSRMPF) INTO (COMPNT) KEY(BR_ITEM_IN);
DO WHILE (MORE_COMPNT_RECS);
DELETE FILE(MSBSRMPF);
READ FILE(MSBSRMPF) INTO (COMPNT);
IF BR_PARENTª=BR_ITEM_IN THEN MORE_COMPNT_RECS=NO;
END;
CLOSE FILE(MSBSRMPF);
OPEN FILE(MSBSRMPF) OUTPUT;
/* begin down an assembly chain */
TOP:;
RRN(LVL)=REC_NO; /* point to first component */
SBQ(LVL)=BATCH_SZ; /* set batch size */
CMP(LVL)=CMP_CHAR; /* set compare values */
/* start of loop for next component */
CHAIN: DO UNTIL(REC_NO=9999999);
/* get next component */
VALID_PSTRUC=YES;
READ FILE(PSTRUC) INTO(PSTRUCT) KEY(REC_NO);
IF VALID_PSTRUC=NO THEN RETURN('20');
/* check for control record */
CNTRL_ID=CHAR(PPCIM,3);
IF CNTRL_ID='.PS' THEN RETURN('20');
/* check dates */
IF (EDATM>=TST_DATE) ³ (EDATOª=0 & EDATO<=TST_DATE) THEN DO;
REC_NO=PPNAC; /* outside dates - get next component */
ITERATE CHAIN;
END;
/* get component Item A */
VALID_ITEM_A=YES;
READ FILE(ITEMARRN) INTO(ITEMA_C) KEY(PPCIM);
SELECT;
WHEN(VALID_ITEM_A=NO) RETURN('21'); /* no comp. Item A */
WHEN(PC_IIRECª=PPCIM) RETURN('22'); /* RRNs don't match */
WHEN(PC_ACREC='D') RETURN('23'); /* Item A deleted */
WHEN(SUBSTR(PC_ITNBR,1,1)ª=CCMPI) RETURN('24'); /* compare char */
WHEN(PC_LOLEV>99) RETURN('25'); /* bad low level */
OTHERWISE;
END;
/* Check if this component is an intermediate. */
/* If so, push current parent's values into */
/* arrays, set up work fields with new parent */
/* information and goto top to start down */
/* the chain of the new parent. */
IF (PC_ITTYP='1') ³ (PC_IIFACª=9999999) THEN DO;
/* save current parent values */
RRN(LVL)=PPNAC;
SBQ(LVL)=STD_BAT_QTY;
CMP(LVL)=CMP_CHAR;
/* set up work fields with new parent values */
REC_NO=PPNAC;
STD_BAT_QTY=PR_SBQTY;
CMP_CHAR=SUBSTR(PC_ITNBR,1,1);
/* increase current level */
LVL=LVL+1;
GOTO TOP;
END;
/* get component Item C */
READ FILE(ITEMAC) INTO (CFMT) KEY(PC_ITNBR);
/* extend component qty & convert to lbs */
WRK_QTY=BATCH_SZ/STD_BAT_QTY*QTYPR;
SELECT;
WHEN(PC_UNMSR='LB');
WHEN(PC_UNMSR='GA') WRK_QTY=WRK_QTY*MC#GAL;
WHEN(PC_UNMSR='GM') WRK_QTY=WRK_QTY/453.59;
WHEN(PC_UNMSR='FL') WRK_QTY=(WRK_QTY*MC#GAL)/128;
WHEN(PC_UNMSR='OZ') WRK_QTY=WRK_QTY/16;
WHEN(PC_UNMSR='LY') DO;
READ FILE(MSFILMPF) INTO(RMFILM) KEY(PC_ITNBR);
IF VALID_RMFILM THEN DO;
WRK_QTY=WRK_QTY*RF_WIDTH*RF_THICKNESS*.155844*MC#GAL;
END;
ELSE RETURN('26'); /* no MSFILMPF record */
END;
OTHERWISE;
END;
/* write out COMPNT */
BR_COMP_QTY=WRK_QTY;
BR_PARENT=BR_ITEM_IN;
BR_COMPONENT=SUBSTR(PC_ITNBR,1,6);
WRITE FILE(MSBSRMPF) FROM (COMPNT) KEYFROM(*);
REC_NO=PPNAC;
END; /* DO group */
/* At this point, we have reached the end of an */
/* assembly chain (PPNAC=9999999). Check to see */
/* if we encountered any intermediates along the */
/* way. If we did, pull back up one level and */
/* continue down the previous parent's chain. */
DO WHILE(LVL>1);
LVL=LVL-1;
IF RRN(LVL)ª=9999999 THEN DO;
REC_NO=RRN(LVL);
STD_BAT_QTY=SBQ(LVL);
CMP_CHAR=CMP(LVL);
GOTO CHAIN;
END;
END;
RETURN('00'); /* DONE! */
END MSD710P;</pre>
</div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-6924840697875489562012-05-02T20:45:00.004-04:002012-05-22T21:04:14.406-04:00Code Generation circa 1988 using RPG II 1/2<div dir="ltr" style="text-align: left;" trbidi="on">
While cleaning out my shelves I came across this old code sample disk. The company is long gone and the language is well…small. RPG II’s roots went back to punch-card days:<br />
<ul>
<li>Column position on each line was important</li>
<li>Column 6 contains a one letter “record type”, e.g. H = header, C = calculation</li>
<li>The OPCODE in the middle of the calc spec was max 6 chars long, e.g. EXSR = execute subroutine.</li>
</ul>
If I remember, the “1/2” was a commercial 3rd party tool/enhancement that added stuff like “IF” and “DO” instead of having to use the left-hand indicators (e.g. N90) to condition execution of the line.<br />
<span style="font-family: 'Courier New';">0001 H 024 B 1 SAL010<br />0002 H*===================================================================<br />0003 H*@ PROPERTY OF XXXXXXXXXXXX, KEENE, NEW HAMPSHIRE 1988<br />0004 H*T Generate #GSORT OCL to retrieve customer/item sales history<br />0005 H*M 144 07Dec88 Written *** Uses RPG II 1/2 ***<br />0005 H*D Accepts up to 18 selection criterion and generates the necessary<br />0005 H*D OCL code to run #GSORT to extract/sort the customer/item sales<br />0005 H*D history file. The calling report proc is stored in LDA to<br />0005 H*D determine various report-specific sort specs such as the header<br />0005 H*D and field specs. To add another procedure the following must<br />0005 H*D be done: Add proc name to PROC array, add the new sort header<br />0005 H*D spec to HDR, add the record type spec(s) to REC if necessary,<br />0006 H*S EDIT$ Edits the selection criteria<br />0006 H*S INIT$ Program Initialization<br />0009 H*I 40-57 Screen error indicators.<br />0014 H*===============================================================<br />0015 FWORKSTN CD E WORKSTN<br />0019 FPROC O 120 120 DISK<br />0021 E* workstation arrays<br />0022 E $FN 18 2 0 field number<br />0022 E $OP 18 2 operation code<br />0022 E $CR 18 15 selection criteria<br />0021 E* program work arrays<br />0022 E OPNS 6 6 2 operation codes<br />0022 E PROC 8 8 6 procedure names<br />0022 E TABPRC 8 8 6 TABNUM 2 0 proc names & # of #GSORT field specs<br />0021 E* sort specs (OCL code)<br />0022 E BEG 1 5 80 common 'beginning' OCL statements<br />0022 E HDR 1 8 80 header specs<br />0022 E REC 1 11 80 record selection specs<br />0037 I UDS<br />0038 I 1 8 @USER<br />0039 I 9 10 @WS<br /> I 505 512 @PROC ?WS? + ?TIME?<br />0040 C*==============================================HILOEQ===========<br />0042 C #@INIT IFNE 1<br />0043 C EXSR INIT$<br />0044 C END<br /> C*<br /> C T$1000 TAG<br /> C EXFMTSCRN100<br /> C KG SETON U7<br /> C KG GOTO T$9999<br /> C* call edit routine to check for errors<br /> C EXSR EDIT$<br /> C* if any error occured, redisplay screen<br /> C #@ERR IFEQ 1<br /> C GOTO T$1000<br /> C END<br /> C* if Cmd/1 wasn't pressed loop back and redisplay<br /> C NKA GOTO T$1000<br /> C* set array element pointer for procedure name<br /> C SETOF 90<br /> C Z-ADD1 Z 20<br /> C @PROC LOKUPPROC,Z 90<br /> C N90 DO<br /> C SETON U7 *proc not found - cancel job<br /> C GOTO T$9999<br /> C END<br /> C* display 'prompt' screen<br /> C EXCPTWK110<br /> C* output // COPY statement with proc name<br /> C EXCPTOCL1<br /> C* output common begining sort specs<br /> C DO 5 X<br /> C EXCPTOCL2<br /> C END<br /> C* output sort header spec<br /> C EXCPTOCL3<br /> C* output user-selected record type specs<br /> C MOVE *BLANKS #AND *clear 'AND' code<br /> C DO 18 X<br /> C $FN,X IFGE 1 *assume if valid $FN<br /> C $FN,X IFLE 18 * then valid $OP and $CR<br /> C SETOF 90<br /> C Z-ADD1 Y 20<br /> C $OP,X LOKUPOPNS,Y 90*assume valid OPN since passed EDIT$<br /> C EXCPTOCL4<br /> C END<br /> C MOVE 'A' #AND *set 'AND' code for remainder of loop<br /> C END<br /> C* output field records for this proc<br /> C DO 28 X<br /> C SETOF 90<br /> C @PROC IFEQ PNAM,X<br /> C EXCPTOCL5<br /> C END<br /> C END<br /> C*==============================================HILOEQ===========<br /> CSR EDIT$ BEGSR<br /> C*<br /> C Z-ADD0 #@ERR 10 *clear error flag<br /> C DO 18 X 20 .DO once for each screen line<br /> C X ADD 39 Y 20 point to screen indicator<br /> C Z-ADD0 *IN,Y clear screen indicator<br /> C* if field num is blank, blank out operation and criterion<br /> C $FN,X IFEQ *BLANKS<br /> C $FN,X OREQ *ZEROS<br /> C MOVE *BLANKS $OP,X<br /> C MOVE *BLANKS $CR,X<br /> C GOTO EDITX<br /> C END<br /> C* if operation is blank, blank out field num and criterion<br /> C $OP,X IFEQ *BLANKS<br /> C $OP,X OREQ *ZEROS<br /> C MOVE *ZEROS $FN,X<br /> C MOVE *BLANKS $CR,X<br /> C GOTO EDITX<br /> C END<br /> C* check for valid field number range<br /> C $FN,X IFLT 1<br /> C $FN,X ORGT 11<br /> C Z-ADD1 *IN,Y turn on corresponding indicator<br /> C Z-ADD1 #@ERR set error flag<br /> C END<br /> C* check for valid operation code<br /> C SETOF 90<br /> C $OP,X LOKUPOPNS 90<br /> C N90 Z-ADD1 *IN,Y turn on corresponding indicator<br /> C N90 Z-ADD1 #@ERR set error flag<br /> C END .END<br /> C*<br /> C EDITX TAG<br /> C*<br /> CSR ENDSR<br /> C*==============================================HILOEQ==========<br /> OPROC E OCL1<br /> O 23 '// COPY LIBRARY-P,NAME-'<br /> O @PROC 31<br /> O E OCL2<br /> O COM,X 80<br /> O E OCL3<br /> O HDR,Z 80<br /> O E OCL4<br /> O REC,X 80<br /> O #AND 7<br /> O OPN,Y 18<br /> O $CR,X 34<br /> O E OCL5<br /> O FLD,X 80<br />** operation codes<br />EQGEGTLELTNE<br />** procedure names<br />SAL299SAL297SAL296SAL295SAL294SAL293SAL292SAL291<br />** table of procedure names & number of sort field specs<br />SAL29905SAL29703SAL29603SAL29503SAL29403SAL29303SAL29205SAL29103<br />** common 'beginning' sort specs<br />// REGION SIZE-64<br />// LOAD #GSORT<br />// FILE NAME-INPUT,LABEL-PRO.SCD,DISP-SHR<br />// FILE NAME-OUTPUT,LABEL-SAL010?WS?<br />// RUN<br />** header specs for each program<br />// HSORTA 17A 3 N *SAL299<br />// HSORTA 18A 3 N *SAL297<br />// HSORTA 18A 3 N *SAL296<br />// HSORTA 5A 3 N *SAL295<br />// HSORTA 18A 3 N *SAL294<br />// HSORTA 18A 3 N *SAL293<br />// HSORTA 8A 3 N *SAL292<br />// HSORTA 18A 3 N *SAL291<br />** common record selection and field specs (insert AND code & test condition)<br />// I C 3 8 D *customer number<br />// I C 9 23 C *item number<br />// I C 36 36 C *sbu<br />// I C 37 38 C *product group<br />// I C 548 548 C *product line<br />// I C 549 550 C *product class<br />// I C 39 40 C *item class<br />// I C 41 42 C *customer type<br />// I C 43 44 C *company code<br />// I C 33 34 C *sales region<br />// I C 35 35 C *sales territory<br />** proc names and their respective #GSORT field specs<br />SAL299// FNC 33 34 *sales region</span></div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-12110373006355285622012-02-19T22:29:00.001-05:002012-02-19T22:29:09.465-05:00Simple Circles–NHibernate Unit Testing (Part 7c)<div dir="ltr" style="text-align: left;" trbidi="on">
This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.<br />
<br />
In <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesnhibernate-repository.html">Part 7a</a> I implemented the Repository pattern using NHibernate and in <a href="http://pragmatic-software.blogspot.com/2012/02/simple-circlesnhibernate-mapping-part.html">Part 7b</a> I used Fluent NHibernate to implement the Data Mapper pattern between the domain layer and the relational database layer. In this post I’ll build unit tests to exercise these implementations.<br />
<br />
One of the problems with attempting to test a data access strategy is ensuring the database is in a known state at the start of each test. Previously I’ve used teardown and setup SQL scripts to empty out data and preload initial values in a database instance. That approach is tedious because it means maintaining two sets of scripts in a different syntax (SQL instead of C#) and using a different toolset (SSMS). Another approach that’s becoming more popular and prevalent is to use a lighter footprint database engine capable of running in-memory. In fact, Fluent NHibernate makes this easy with its standard configuration – all it takes is setting up an NHibernate session configured to use the in-memory database as shown here:<br />
<br />
<span style="font-size: large;">SessionFactory Class</span><br />
<pre class="c-sharp" name="code">namespace Circles.NHibernateTests
{
using Circles.NHibernateRepository;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
public class SessionFactory
{
private static Configuration staticConfig;
public static ISessionFactory CreateSessionFactory()
{
return
Fluently.Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<PartyRepository>().ExportTo(System.Console.Out))
.ExposeConfiguration((c) => staticConfig = c)
.BuildSessionFactory();
}
public static void BuildSchema(ISession session)
{
var export = new SchemaExport(staticConfig);
export.Execute(script: true, export: true, justDrop: false, connection: session.Connection, exportOutput: null);
}
}
}</pre>
Lines 20-22 contain all the “magic”: line 20 configures the database to use the standard in-memory configuration for SQLite. Line 21 sets up the mappings to be read from the <span style="font-family: 'Courier New', Courier, monospace;">PartyRepository</span> assembly; in addition, the ExportTo() method call will dump the generated hbm.xml to the console. Line 22 exposes the configuration being set up before it is passed to NHibernate for session creation. In this case, the Lambda expression stores the newly built configuration in a static variable for later reuse by the BuildSchema method.<br />
<br />
xUnit does not implement or use constructs such as <span style="font-family: 'Courier New';">[Setup]</span> / <span style="font-family: 'Courier New';">[Teardown]</span> like nUnit does or <span style="font-family: 'Courier New';">[TestInitialize]</span> / <span style="font-family: 'Courier New';">[TestCleanup]</span> like MSTest does since the authors feel it is problematic. You can read more about the rational on James Newkirk’s blog post “<a href="http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html" target="_blank">Why you should not use Setup and TearDown in NUnit</a>”. Pretty compelling when the main author himself tells you not to; however, I’m going to bend the rules a little. I’ve implemented a base testing class that contains a virtual method called <span style="font-family: 'Courier New';">TestInitialize()</span> whose purpose is to prepare the testing database and put it in a known state before each test is executed:<br />
<br />
<span style="font-size: large;">TestBase Class</span><br />
<pre class="c-sharp" name="code">namespace Circles.NHibernateTests
{
using NHibernate;
/// <summary>
/// Base class for NHibernate / SQLite tests
/// </summary>
public abstract class TestBase
{
protected static readonly object LockObject = new object();
private static ISessionFactory sessionFactory;
protected ISession Session { get; set; }
/// <summary>
/// Code to run before the test to allocate
/// and configure any resources needed.
/// </summary>
public virtual void TestInitialize()
{
sessionFactory = SessionFactory.CreateSessionFactory();
Session = sessionFactory.OpenSession();
SessionFactory.BuildSchema(Session);
}
public void Dispose()
{
Session.Dispose();
}
}
}</pre>
<br />
Each test class can now easily prepare an in-memory database and place it in a known state prior to executing tests by overriding <span style="font-family: 'Courier New';">TestInitialize()</span> with its own specific behavior:<br />
<br />
<span style="font-size: large;">TestInitialize() Method</span><br />
<pre class="c-sharp" name="code">public override void TestInitialize()
{
Monitor.Enter(LockObject);
base.TestInitialize();
using (var tx = Session.BeginTransaction())
{
var householdType = new PartyType(new Guid(Constants.PartyTypeIdHousehold))
{
TypeName = "Household"
};
Session.Save(householdType);
var personType = new PartyType(new Guid(Constants.PartyTypeIdPerson))
{
TypeName = "Person"
};
Session.Save(personType);
var person = new Person
{
FirstName = "Nancy",
LastName = "Davolio",
Gender = GenderEnum.Female,
Birthday = new DateTime(1948, 12, 8),
PartyType = personType
};
Session.Save(person);
Session.Flush();
tx.Commit();
}
Session.Clear();
Monitor.Exit(LockObject);
}</pre>
<br />
The <span style="font-family: 'Courier New';">Monitor.Enter</span> and <span style="font-family: 'Courier New';">Monitor.Exit</span> calls (lines 3 & 38) ensure that access to the NHibernate Session remains serialized and two test methods can’t accidently interfere with each other in multi-threaded harnesses. The first call is to the base class’ implementation which creates the in-memory database. Following that I create PartyType instances for Household and Person and then create and persist a well-known Person instance.<br />
<br />
With the base class and SessionFactory implemented and in place, constructing unit tests that can exercise (indirectly) the mappings as well as an actual, deployed database layer becomes trivial:<br />
<br />
<span style="font-size: large;">CanAddHousehold() Test Method</span><br />
<pre class="c-sharp" name="code">[Fact]
public void CanAddHousehold()
{
this.TestInitialize();
IPartyRepository repository;
Household household;
// arrange
using (var tx = Session.BeginTransaction())
{
repository = new PartyRepository(Session);
var partyType = repository.FindPartyTypeById(new Guid(Constants.PartyTypeIdHousehold));
// act
household = new Household
{
PartyName = "Eisenhower",
FormalGreeting = "President Dwight D. and Mrs. Mamie",
InformalGreeting = "Ike and Mamie",
PartyType = partyType
};
repository.Add(household);
tx.Commit();
}
// assert
Assert.NotNull(household);
Assert.NotNull(repository.FindById(household.PartyId));
}</pre>
<br />
Line 4 initializes the database including preparing the known state, Line 12 initializes a <span style="font-family: 'Courier New';">PartyRepository</span> instance using the in-memory database session. This particular line of code deserves special attention – I’m creating a <span style="font-family: 'Courier New';">PartyRepository</span> and giving it the in-memory database to operate against. Recall in <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesnhibernate-repository.html">Part 7a</a> on Line 47 of the fourth code fragment (<span style="font-family: 'Courier New';">DBSession</span> class) that a <span style="font-family: 'Courier New';">PartyRepository</span> instance was created using the “real” NHibernate <span style="font-family: 'Courier New';">DbSession</span> there. Here’s where designing the NHibernate repository to accept an <span style="font-family: 'Courier New';">ISession</span> implementation gives flexibility.<br />
<br />
Line 13 retrieves the household party type that is known to be there because it was created and saved during <span style="font-family: 'Courier New';">TestInitialize()</span>. Finally the household is created and saved. An interesting side effect of this test was when I first ran it – it failed. I had forgotten to specify/assign a <span style="font-family: 'Courier New';">PartyType</span> to the household instance. When I referred back to the <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesfake-repository-part-3.html">earlier tests</a> that I put together using the FakeRepository I realized that it too wasn’t assigning or checking the party type. This oversight illustrates a problem with trying to fake or mock an implementation – you have to remember to code and test all the validation and business rules necessary to be a “real” repository. This is the best reason to have taken these steps of setting up a reusable, fast way to test the real repository – as you code the repository, you can test it without having to write double the code by updating the fake one.<br />
<br />
This discovery led to adding a negative test to ensure the repository doesn’t allow a household without a party type:<br />
<br />
<span style="font-size: large;">Negative Test</span><br />
<pre class="c-sharp" name="code">[Fact]
public void CanNotAddHouseholdWithMissingPartyType()
{
this.TestInitialize();
// arrange
using (var tx = Session.BeginTransaction())
{
var repository = new PartyRepository(Session);
// act
var household = new Household
{
PartyName = "Eisenhower",
FormalGreeting = "President Dwight D. and Mrs. Mamie",
InformalGreeting = "Ike and Mamie",
/* PartyType = partyType */
};
// assert
Assert.Throws<NHibernate.PropertyValueException>(
delegate
{
repository.Add(household);
});
tx.Rollback();
}
}</pre>
<br />
Lines 21-25 uses the xUnit <span style="font-family: 'Courier New';">Assert.Throws<></span> method to wrap the attempt to add a household without a party type. If the repository doesn’t throw an <span style="font-family: 'Courier New';">NHibernate.PropertyValueException</span> then the test is considered to have failed.<br />
<br />
This post was pretty densely packed with concepts - an entire framework for testing an NHibernate-based data layer. The accompanying code base is growing larger and can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/ce2fb882617b">here</a>.</div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-87141740272239732042012-02-03T23:28:00.000-05:002012-02-03T23:28:48.738-05:00Simple Circles–NHibernate Mapping (Part 7b)<div dir="ltr" style="text-align: left;" trbidi="on">
This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.<br />
In a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesadd-aspnet-mvc-3-ui-part_15.html">previous post</a>, I used <a href="http://automapper.org/" target="_blank">AutoMapper</a> to implement the DataMapper pattern to map and flatten the <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesdomain-model-part-1.html">domain model</a> into view models for the MVC user interface. The same approach applies to mapping the domain model to a relational database. In fact, this is the heart of an <a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank">object-relational mapping</a> (ORM) tool like NHibernate. Originally, NHibernate used XML-based mapping files similar to its Hibernate lineage. More recently, James Gregory’s <a href="http://fluentnhibernate.org/" target="_blank">Fluent NHibernate</a> tool has emerged as a leading alternative with strengths such as supporting the <a href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">fluent interface</a> programming style, convention-based mappings, and compile-time checking (a huge time saver).<br />
<a href="http://lh5.ggpht.com/-CS9hO4fH7d8/TyyzwiJGd5I/AAAAAAAAAv4/iVU9FN5IsTY/s1600-h/Simple-Circles---Install-FluentNHibe.png"><img align="right" alt="Simple Circles - Install FluentNHibernate" border="0" height="80" src="http://lh5.ggpht.com/-so19acv6hmA/Tyyzw4Hh1jI/AAAAAAAAAwA/VRfpiXE314c/Simple-Circles---Install-FluentNHibe%25255B2%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 0px 0px 0px 3px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Install FluentNHibernate" width="157" /></a>After adding Fluent NHibernate <a href="http://nuget.org/packages/FluentNHibernate/1.2.0.712" target="_blank">v1.2.0.712</a> – that version is compiled against the NHibernate version I’m using – I created a <span style="font-family: 'Courier New';">\Maps</span> folder and created the mapping classes. Before diving into the mapping, it’s time to introduce a best practice for managing concurrency and allowing detection of stale objects. By convention, NHibernate supports a special-named property called ‘<span style="font-family: 'Courier New';">Version</span>’ that can be numeric (preferred), a timestamp or a DB timestamp. You can find more information at the NHibernate site or Ayende’s <a href="http://ayende.com/blog/3946/nhibernate-mapping-concurrency" target="_blank">post</a>. In the Circles data model, I’ve got a base Entity class which is a great place to put the Version property so every Entity automatically gets the benefit of optimistic concurrency checking. Here's the mappings for <span style="font-family: 'Courier New';">Party</span> and <span style="font-family: 'Courier New';">PartyType</span>:<br />
<pre class="c-sharp" name="code">namespace Circles.NHibernateRepository.Maps
{
using Circles.Domain;
using FluentNHibernate.Mapping;
public class PartyMap : ClassMap<Party>
{
public PartyMap()
{
Id(x => x.PartyId).GeneratedBy.GuidComb();
Version(x => x.Version);
References(x => x.PartyType, "TypeId")
.Not.Nullable();
Map(x => x.PartyName)
.Not.Nullable()
.Length(255)
.Index("ukPartyName");
}
}
public class PartyTypeMap : ClassMap<PartyType>
{
public PartyTypeMap()
{
Id(x => x.TypeId).GeneratedBy.GuidComb();
Version(x => x.Version);
Map(x => x.TypeName)
.Not.Nullable()
.Length(255)
.Index("ukTypeName");
}
}
}</pre>
<br />
Line #11 above maps the <span style="font-family: 'Courier New';">Id</span> property to a column called <span style="font-family: 'Courier New';">PartyId</span> and specifies that the <a href="http://nhforge.org/blogs/nhibernate/archive/2009/05/21/using-the-guid-comb-identifier-strategy.aspx" target="_blank">Guid.Comb Identifier Strategy</a> be used to generate new ids. Lines #12 and #13 map the referenced PartyType within a Party by creating a foreign key using <span style="font-family: 'Courier New';">TypeId</span> as the column name.<br />
<br />
Fluent NHibernate has the ability to not only define mappings but to configure NHibernate using the mappings along with other settings you specify. Using this ability, its also possible to export the configuration to <span style="font-family: 'Courier New';">.hbm.xml</span> files combined with NHibernate’s ability to export .hbm files to SQL DDL. There’s a lot of power packed into the following:<br />
<pre class="c-sharp" name="code">namespace NHibernateSchemaExport
{
using Circles.NHibernateRepository;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
class Program
{
static void Main(string[] args)
{
Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.ConnectionString(c => c.FromConnectionStringWithKey("circlesdb"))
.ShowSql)
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<partyrepository>()
.ExportTo("."))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
static void BuildSchema(Configuration cfg)
{
new SchemaExport(cfg)
.SetOutputFile("CirclesSchema.sql")
.Execute(script: true, export: false, justDrop: false);
}
}
}</partyrepository></pre>
<br />
Line #18 shows the <span style="font-family: 'Courier New';">ExportTo()</span> method being using to export the configured mappings to the current directory. Line #19 uses the <span style="font-family: 'Courier New';">ExposeConfiguration()</span> method along with NHibernate’s <span style="font-family: 'Courier New';">SchemaExport()</span> method on line #26 to output the database schema. These techniques give us the ability to “see into” the dynamically generated hbm and sql files.<br />
<br />
There’s more details in the accompanying change set for this post that can be downloaded <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/904993bb0f4d" target="_blank"><strong>here</strong></a>. Next up is implementing the PartyRepository now that NHibernate is configured and the domain-to-database mapping is coming together.</div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-14212704692690309402012-01-29T09:50:00.000-05:002012-01-29T09:53:51.265-05:00Simple Circles–NHibernate Repository (Part 7a)<div dir="ltr" style="text-align: left;" trbidi="on">
This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.<br />
I’ve got a decent foundation in place with the <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesdomain-model-part-1.html">domain model</a>, <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlespersistence-part-2.html">persistence interface</a> defining the repository pattern and a concrete implementation with a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesfake-repository-part-3.html">fake repository</a> for testing purposes. The fake repository also serves to easily and quickly validate the design – if it is difficult to implement with simple in-memory structures then it’ll likely be even harder using an ORM. I have more experience with NHibernate and it’s a more sophisticated and mature ORM so I’ll start with it first.<br />
To begin with, I’ve added two interfaces to the Persistence class library to define a database session and a <a href="http://www.dofactory.com/Patterns/PatternAbstract.aspx" target="_blank">factory pattern</a> to manage creating sessions.<br />
<pre class="c-sharp" name="code">namespace Circles.Persistence
{
using System;
using System.Data;
public interface IDbSession : IDisposable
{
void BeginTransaction(IsolationLevel isolationLevel);
void Commit();
void Rollback();
IPartyRepository CreatePartyRepository();
}
}</pre>
Bob Cravens provided inspiration for the session work with his <a href="http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/" target="_blank">Truck Management System</a>. that eventually made it into his own <a href="https://github.com/rcravens/GenericRepository" target="_blank">GenericRepository</a> project. This database session interface specifies that concrete implementations provide <span style="font-family: 'Courier New';">BeginTransaction</span>, <span style="font-family: 'Courier New';">Commit</span>, and <span style="font-family: 'Courier New';">Rollback</span> methods as well as a concrete implementation for creating a <span style="font-family: 'Courier New';">PartyRepository</span>.<br />
The <span style="font-family: 'Courier New';">DbSessionFactory</span> defines the factory pattern with a little bit of flexibility – you can create a <span style="font-family: 'Courier New';">DbSession</span> with or without transactional support.<br />
<pre class="c-sharp" name="code">namespace Circles.Persistence
{
public interface IDbSessionFactory
{
IDbSession Create(bool withTransaction);
}
}</pre>
<a href="http://lh6.ggpht.com/-UvFkmtPAi0s/TyVcKb6bjcI/AAAAAAAAAvo/tPvx7BVzej8/s1600-h/Simple%252520Circles%252520-%252520Install%252520NHibernate%25255B3%25255D.png"><img align="right" alt="Simple Circles - Install NHibernate" border="0" height="73" src="http://lh5.ggpht.com/-lqi1sYP9JBI/TyVcLRam90I/AAAAAAAAAvw/G2tOq3El1HA/Simple%252520Circles%252520-%252520Install%252520NHibernate_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 0px 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Install NHibernate" width="191" /></a>Next I created an <span style="font-family: 'Courier New';">NHibernateRepository</span> class library project and added the NHibernate package via NuGet. While NuGet makes it simple to install packages and their dependencies, it doesn’t relieve you from managing versions. It is usually best to specify an explicit version when installing packages to ensure you don’t get conflicts and other surprises. In my case I used “<span style="font-family: 'Courier New';">-version 3.1.0.4000</span>” which also installs the same version of <span style="font-family: 'Courier New';">Iesi.Collections</span>.<br />
The implementation of DbSessionFactory is pretty lightweight and trivial:<br />
<pre class="c-sharp" name="code">namespace Circles.NHibernateRepository
{
using System.Data;
using Circles.Persistence;
public class DbSessionFactory : IDbSessionFactory
{
public IDbSession Create(bool withTransaction)
{
DbSession session = new DbSession(SessionProvider.SessionFactory);
if (withTransaction)
{
session.BeginTransaction(IsolationLevel.ReadCommitted);
}
return session;
}
}
}</pre>
<br />
The <span style="font-family: 'Courier New';">SessionProvider</span> class used in line #10 above will be discussed below. <span style="font-family: 'Courier New';">DbSession</span> is also lightweight because it delegates the heavy lifting to the underlying NHibernate methods:<br />
<pre class="c-sharp" name="code">namespace Circles.NHibernateRepository
{
using System;
using System.Data;
using Circles.Persistence;
using NHibernate;
public class DbSession : IDbSession
{
private readonly ISession session;
private ITransaction transaction;
public DbSession(ISessionFactory sessionFactory)
{
if (sessionFactory == null)
{
throw new ArgumentNullException("sessionFactory");
}
this.session = sessionFactory.OpenSession();
this.session.FlushMode = FlushMode.Auto;
}
~DbSession()
{
this.Dispose();
}
public void Dispose()
{
if (this.session == null)
{
return;
}
lock (this.session)
{
if (this.session.IsOpen)
{
this.session.Close();
}
}
GC.SuppressFinalize(this);
}
public IPartyRepository CreatePartyRepository()
{
return new PartyRepository(this.session);
}
public void BeginTransaction(IsolationLevel isolationLevel)
{
this.transaction = this.session.BeginTransaction(isolationLevel);
}
public void Commit()
{
if (this.transaction == null)
{
return;
}
if (!this.transaction.IsActive)
{
throw new InvalidOperationException("No active transation");
}
this.transaction.Commit();
}
public void Rollback()
{
if (this.transaction == null)
{
return;
}
if (this.transaction.IsActive)
{
this.transaction.Rollback();
}
}
}
}</pre>
<br />
NHibernate is highly configurable so instantiating the libraries requires processing configuration settings contained in <span style="font-family: 'Courier New';">hibernate.cfg.xml</span> as well as reflecting over your assemblies. Doing so is expensive – its best to cache the initialized configuration and session for the lifetime of the application. The <span style="font-family: 'Courier New';">SessionProvider</span> class does this:<br />
<pre class="c-sharp" name="code">namespace Circles.NHibernateRepository
{
using NHibernate;
using NHibernate.Cfg;
public class SessionProvider
{
private static Configuration configuration;
private static ISessionFactory sessionFactory;
private SessionProvider()
{
}
public static Configuration Configuration
{
get
{
if (configuration == null)
{
configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly(typeof(PartyRepository).Assembly);
}
return configuration;
}
}
public static ISessionFactory SessionFactory
{
get { return sessionFactory
?? (sessionFactory = Configuration.BuildSessionFactory()); }
}
public static ISession GetSession()
{
return SessionFactory.OpenSession();
}
}
}</pre>
<br />
That’s a lot of implementation and setup plumbing! The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/892d3eae3db5" target="_blank">here</a>. The next installment will map the domain model to the relational database model.</div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-40091118683000114412012-01-22T10:50:00.000-05:002012-01-22T11:01:55.366-05:00Simple Circles–Enabling jQuery UI (Part 6)<div dir="ltr" style="text-align: left;" trbidi="on">
This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.<br />
I think of the default blue MVC 3 UI as something of a developer’s test version – not really what you’ll go to production with but sufficient to work with while developing. It’s possible to use the ASP.NET MVC themes from their gallery but I think jQuery and its companion jQuery UI provide a much richer and cross-browser solution with far less effort.<br />
<h2>
Themes</h2>
Steve Hobbs wrote a great <a href="http://stevescodingblog.co.uk/adding-a-new-jquery-ui-theme-to-the-default-asp-net-mvc-3-project/" target="_blank">step-by-step post</a> on enabling jQuery UI last June. Like him, I used the Redmond theme to start with so it more closely resembled the default.<br />
<a href="http://lh6.ggpht.com/-0qpFGeMymeY/Txwk6zMuJdI/AAAAAAAAAuI/B0-RIpmHAL0/s1600-h/Simple-Circles---Enable-jQuery-UI3.png"><img align="right" alt="Simple Circles - Enable jQuery UI" border="0" height="69" src="http://lh4.ggpht.com/-_yVTJr0fsUM/Txwk7h6F8HI/AAAAAAAAAuQ/q9oSiJNUZfA/Simple-Circles---Enable-jQuery-UI_th.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 0px 0px 0px 2px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Enable jQuery UI" width="213" /></a><a href="http://lh4.ggpht.com/-3_JD0No5bHI/Txwk7ssRvlI/AAAAAAAAAuY/R2p5Jygqi2U/s1600-h/Simple-Circles---jQuery-UI-theme3.png"><img align="left" alt="Simple Circles - jQuery UI theme" border="0" height="138" src="http://lh4.ggpht.com/-ERp5Nm_UNTs/Txwk79UkosI/AAAAAAAAAug/XiYW1fl1gjQ/Simple-Circles---jQuery-UI-theme_thu.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: left; margin: 0px 5px 0px 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - jQuery UI theme" width="142" /></a>After downloading the <a href="http://jqueryui.com/themeroller/" target="_blank">Redmond</a> theme, copy the <span style="font-family: 'Courier New';">css\redmond</span> folder to the <span style="font-family: 'Courier New';">Content\themes</span> folder under the Circles website. Remember to choose “Include in Project” from the Solution Explorer (see image to the left). As Steve Hobbs indicates, jQuery UI support is already included in the ASP.NET MVC 3 templates – it just needs to be enabled by adding two lines to the <span style="font-family: 'Courier New';">_Layout.cshtml</span> in the <span style="font-family: 'Courier New';">Shared</span> folder as shown on the right. To start taking advantage of the jQuery UI theme, simply add the appropriate styles to HTML elements. Here I’ve commented out the standard Submit button on the <span style="font-family: 'Courier New';">Create.cshtml</span> page and replaced it with one decorated with jQuery UI CSS classes:<br />
<pre class="html" name="code"><!--<input type="submit" value="Create" />-->
<input type="submit" value="Create"
class="ui-button ui-widget ui-state-default ui-corner-all"
role="button" aria-disabled="false"></pre>
<br />
<a href="http://lh5.ggpht.com/-UPg3mkTVYzg/Txwk8HlA0dI/AAAAAAAAAuo/6LAHYTb4KCM/s1600-h/Simple-Circles---jQuery-button3.png"><img align="right" alt="Simple Circles - jQuery button" border="0" height="109" src="http://lh5.ggpht.com/-4Cw5mqtIQ0E/Txwk8dmL77I/AAAAAAAAAuw/mU2ISkhIqcM/Simple-Circles---jQuery-button_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - jQuery button" width="136" /></a>This screen shot shows the before and after using the Redmond theme just set up. These CSS classes are designed such that switching themes is as easy as deploying a different theme to the <span style="font-family: 'Courier New';">Content\themes</span> folder and changing the single <link> line in the <span style="font-family: 'Courier New';">_Layout.cshtml</span> page. The “eye candy” is nice – it looks fresher and more modern…well, months ahead of the default hard images the browser displays!<br />
<br />
Next I’m going to add some feedback for the user when an action completes. The default behavior when adding, updating or deleting an entity is to perform the action then return the user to the Index page. Breaking this down, it means the controller performs the action then uses <span style="font-family: 'Courier New';">RedirectToAction</span> to redirect the browser to the default HTTP GET action. Doing so ensures that the user can’t accidently use refresh to repeat the same action, e.g. adding the same entity twice or, classically, buying the same thing again.<br />
<br />
Because redirect is used the current HTTP request ends and another one initiates. This means the feedback message has to be passed <u>across</u> HTTP requests so the usual suspect – <span style="font-family: 'Courier New';"><a href="http://msdn.microsoft.com/en-us/library/ie/system.web.mvc.viewpage.viewdata.aspx" target="_blank">ViewData</a></span> – won’t work. The MVC engineers planned for this with another dictionary object that’s briefly stored in the user’s session – <a href="http://msdn.microsoft.com/en-us/library/ie/dd394711.aspx" target="_blank">TempData</a>. The MSDN article <a href="http://msdn.microsoft.com/en-us/library/ie/dd394711.aspx" target="_blank">Passing Data in an ASP.NET MVC Application</a> provides the necessary details. Here I tuck the confirmation message into <span style="font-family: 'Courier New',Courier,monospace;">TempData</span> (line #4) before issuing the redirect:<br />
<pre class="c-sharp" name="code"> ...
this.repository.Add(entity);
TempData["message"] = string.Format("{0} was added", entity.PartyName);
return RedirectToAction("Index");
}</pre>
<br />
Back in the <span style="font-family: 'Courier New',Courier,monospace;">Index.cshtml</span> the message just passed to it is retrieved and rendered with jQuery UI classes decorating the output:<br />
<pre class="html" name="code"><h2>People</h2>
@if (TempData["message"] != null) {
<div style="margin-top: 20px; padding: 0 .7em;" class="ui-state-highlight ui-corner-all">
<p><span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-info"></span>
@TempData["message"]
</p>
</div>
}</pre>
<br />
<a href="http://lh4.ggpht.com/-SXGr8R71qBE/Txwk8hsRr7I/AAAAAAAAAu4/jnygKqhYKUM/s1600-h/Simple-Circles---Confirmation3.png"><img align="right" alt="Simple Circles - Confirmation" border="0" height="116" src="http://lh5.ggpht.com/-tQOSf8o-pZM/Txwk83aZX_I/AAAAAAAAAvA/DFYPs6ZkQyc/Simple-Circles---Confirmation_thumb1.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Confirmation" width="178" /></a>The result is shown to the right. Another simple feature to take advantage of jQuery’s client-side power is to enable “unobtrusive client-side validation”. There’s plenty of examples already, including the ASP.NET Teams’s own <a href="http://www.asp.net/mvc/tutorials/creating-a-mvc-3-application-with-razor-and-unobtrusive-javascript" target="_blank">tutorial</a>. Two web.config settings and two more <span style="font-family: 'Courier New';"><link></span> elements to include necessary JavaScript files in <span style="font-family: 'Courier New';">_Layout.cshtml</span> and field/form validation moves from server-side down to client-side to provide feedback without having to HTTP POST the form to the server then getting the validation messages sent back to the client browser.<br />
<h2>
Menu Tabs and Lists</h2>
<a href="http://lh6.ggpht.com/-1ptIEgFThOs/Txwk89QCI9I/AAAAAAAAAvI/GlgsJdBKdlM/s1600-h/Simple%252520Circles%252520-%252520Tabbed%252520Menu%25255B3%25255D.png"><img align="right" alt="Simple Circles - Tabbed Menu" border="0" height="72" src="http://lh3.ggpht.com/-g6kqByqhDpM/Txwk9E3G4tI/AAAAAAAAAvQ/Fzp2aoiV7y4/Simple%252520Circles%252520-%252520Tabbed%252520Menu_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 0px 0px 0px 3px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Tabbed Menu" width="177" /></a>Once again I’m turning to the ASP.NET team’s tutorials to improve the user experience even more. Their <a href="http://www.asp.net/mvc/tutorials/contact-manager/iteration-2-make-the-application-look-nice-cs" target="_blank">Iteration #2 – Make the application look nice</a> article contains two enhancements; one improves the menu tabs by rounding the corners and providing highlighting to indicate the selected tab the user is on and the other replaces the textual hyperlinks on each row with graphics for edit and delete. <a href="http://lh3.ggpht.com/-_DrTU7fUfi8/Txwk9dedIVI/AAAAAAAAAvY/wtVbFxKAq6k/s1600-h/Simple%252520Circles%252520-%252520Nicer%252520Lists%25255B3%25255D.png"><img align="right" alt="Simple Circles - Nicer Lists" border="0" height="195" src="http://lh5.ggpht.com/-TMHnkd8NNh8/Txwk9gCWBxI/AAAAAAAAAvg/9d6-44R8SKg/Simple%252520Circles%252520-%252520Nicer%252520Lists_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Nicer Lists" width="145" /></a>Again, rather than duplicating details here, please refer to the article for more information. The result of these efforts is shown on the right.<br />
<br />
The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/ab14df6388a6" target="_blank">here</a>. The next several installments will flesh out concrete implementations of the repository using Entity Framework and NHibernate.</div>Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-72134163263053243412012-01-19T06:00:00.000-05:002012-01-20T08:03:33.174-05:00Simple Circles–MVC Controller Unit Tests (Part 5)<div style="text-align: left" dir="ltr" trbidi="on">This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.</div> <div style="text-align: left" dir="ltr" trbidi="on"><br><a href="http://lh4.ggpht.com/-YRDoS4lwAws/TxjhEbp6OjI/AAAAAAAAAt0/iEnzkrbfbqY/s1600-h/Simple%252520Circles%252520-%252520ControllerTests%25255B3%25255D.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 3px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Simple Circles - ControllerTests" border="0" alt="Simple Circles - ControllerTests" align="right" src="http://lh4.ggpht.com/-IXW0vyDGnIk/TxjhEmy9a6I/AAAAAAAAAt8/LvymwD__zl8/Simple%252520Circles%252520-%252520ControllerTests_thumb%25255B1%25255D.png?imgmax=800" width="144" height="162"></a>In the <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesadd-aspnet-mvc-3-ui-part_15.html">last post</a> I left off with the <span style="font-family: courier new">PeopleController</span> refactored to use an <span style="font-family: courier new">IPartyRepository</span> via dependency injection. Now I’ll create unit tests for the controller so that we’ll know if something breaks as the solution evolves. Since I’m planning on several views and controllers, I added a <span style="font-family: courier new">ControllerTests</span> folder to the <span style="font-family: courier new">UnitTests</span> project to organize and group them together. With <a href="http://xunit.codeplex.com/" target="_blank">xUnit</a>, as with many unit testing frameworks, simply add a new class called <span style="font-family: courier new">PeopleControllerTest</span> and begin writing the tests.</div> <div style="text-align: left" dir="ltr" trbidi="on"><br>Unit testing MVC controllers generally falls into two categories:</div> <div style="text-align: left" dir="ltr" trbidi="on"> <ol> <li>Ensuring that an action result being returned from a controller’s action is correct. On HTTP GET requests, this means the correct view result is returned. <li>Ensuring that HTTP POSTs are behaving properly: <ol style="list-style-type: lower-alpha"> <li>A POST with purposely invalid model data causes it to route the request back to the originating view. <li>A POST with correct model data causes it to route back to the Index view.</li></ol></li></ol></div>Because of the dependency injection work just done, setting up the unit test is straightforward:<br><pre class="c-sharp" name="code">[Fact]<br>public void DefaultGetReturnsIndexView()<br>{<br> // arrange<br> const string ExpectedViewName = "Index";<br> var peopleController = <br> new PeopleController(new FakeRepository.FakePartyRepository());<br><br> // act<br> var viewResult = peopleController.Index();<br><br> // assert<br> Assert.NotNull(viewResult);<br> Assert.Equal(ExpectedViewName, viewResult.ViewName);<br> var model = viewResult.ViewData.Model as IEnumerable<person>;<br> Assert.NotNull(model);<br>}</person></pre><br /><p>Notice on Line #6 above that it’s easy to pass a new instance of the <span style="font-family: courier new">FakeRepository</span> from the test method. The assertions section checks that a view result was returned, that it was the expected named view result and that the view’s model is present.</p><br /><p>Testing the HTTP POST actions is a bit more involved. The basic test is the same however since the testing class is calling the controller directly a little more work is needed. Model validation is a part of the MVC runtime which is not present during testing so it is necessary to “prime the pump” so to speak by placing the error into the controller’s <span style="font-family: courier new">ModelState</span> to see if it’s being handled correctly – this is essentially the same behavior the MVC runtime exhibits:</p><pre class="c-sharp" name="code">[Fact]<br>public void CreatePostReturnsViewIfModelStateIsInvalid()<br>{<br> // arrange<br> const string ExpectedViewName = "Create";<br> var peopleController<br> = new PeopleController(new FakeRepository.FakePartyRepository());<br> peopleController.ModelState.AddModelError("LastName", "LastName is required.");<br> var person = new Person<br> {<br> FirstName = "Henry",<br> MiddleName = "Lewis",<br> //LastName = "Stimson ",<br> Gender = Enum.GetName(typeof(GenderEnum), GenderEnum.Male),<br> Birthday = new DateTime(1867, 9, 21)<br> };<br><br> // act<br> var viewResult = peopleController.Create(person) as ViewResult;<br><br> // assert<br> Assert.NotNull(viewResult);<br> Assert.Equal(ExpectedViewName, viewResult.ViewName);<br>}</pre><br /><p>Line #8 above is where the error is set up. Lines #9 through #16 create a <span style="font-family: courier new">Person</span> instance to pass to the controller method to mimic what the MVC runtime will do. Notice that I commented out the line for setting the <span style="font-family: courier new">LastName</span> property for authenticity purposes. Personally, I would hate to come across some else’s code that sets up an error yet passes in perfectly valid data. Finally, the assert statements check that the same <span style="font-family: courier new">Create</span> view is returned indicating that the error(s) were detected and handled properly.<br><br>Testing for a valid model is nearly the same – just don’t set the <span style="font-family: courier new">ModelState</span>, pass a valid <span style="font-family: courier new">Person</span> instance and check that we’re returned to the Index page. Edit, update and delete actions are nearly identical as well.</p><br /><p>The final bit of code worthy of mention is around the use of <a href="http://automapper.org/" target="_blank">AutoMapper</a> – remember that the <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesadd-aspnet-mvc-3-ui-part_15.html">last post</a> introduced AutoMapper as an implementation of the DataMapper pattern. I wired up the mapping initialization inside <font face="Courier New">Global.asax.cs</font> then. Of course the test harness doesn’t have a website since it’s job is exercising the logic and behavior of the controller classes. Therefore I have to use the xUnit way of introducing a “fixture” necessary for the test class to operate.</p><pre class="c-sharp" name="code">public class PeopleControllerTest : IUseFixture<DataMapperFixture><br />{<br /> public void SetFixture(DataMapperFixture data)<br /> {<br /> data.CreateMaps();<br /> }<br /> ...<br />}<br />...<br />public class DataMapperFixture : IDisposable<br />{<br /> public void CreateMaps()<br /> {<br /> Mapper.AssertConfigurationIsValid();<br /> PersonMap.CreateMaps();<br /> }<br />}</pre><br /><p>The test class implements the xUnit <font face="Courier New">IUseFixture<T></font> interface which tells the xUnit runtime that it needs to call <font face="Courier New">SetFixture</font> with an instance of that type – in my case I created a trivial <font face="Courier New">DataMapperFixture</font> class that simply verifies the mapping is valid and calls the <font face="Courier New">PersonMap.CreateMaps()</font> method to initialize <font face="Courier New">AutoMapper</font>.</p><br /><p>The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/9951d0cc21a4" target="_blank">here</a>. The next installment will explore some simple jQuery enhancements to make the UI a little nicer and more informative. </p> Anonymoushttp://www.blogger.com/profile/14877329227524414343noreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-3728561653614464322012-01-15T10:37:00.000-05:002012-01-15T16:22:47.764-05:00Simple Circles–Add an ASP.NET MVC 3 UI (Part 4b)This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.<br />
<a href="http://lh4.ggpht.com/-jP08VRDvUo4/TwPFVB80BSI/AAAAAAAAAaM/v8YkxyqqxfE/s1600-h/Simple%252520Circles%252520-%252520Ninject%252520package.png"><img align="right" alt="Simple Circles - Ninject package" border="0" height="141" src="http://lh4.ggpht.com/-Skk1Y1gLNIU/TwJpiSZkdcI/AAAAAAAAAaU/W-VWg3hX0dc/Simple%252520Circles%252520-%252520Ninject%252520package_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; float: right; margin: 0px 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Ninject package" width="192" /></a>In the <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesadd-aspnet-mvc-3-ui-part.html">last post</a> I left off with a scaffolded People MVC implementation that was hard-wired to use the Entity Framework 4 data access technology. In this post I’m going to replace that with the <a href="http://ninject.org/" target="_blank">Ninject</a> dependency-injection framework and use the previously built FakePartyRepository implementation to begin testing the UI quickly.<br />
With NuGet, adding Ninject support is easy – just two simple commands: ‘<span style="font-family: 'Courier New';">Install-Package Ninject -Version 2.2.1.4</span>’ and ‘<span style="font-family: 'Courier New';">Install-Package Ninject.MVC3 -Version 2.2.2.0</span>’. I chose to include specific versions since they were specified on the corresponding NuGet Gallery pages. Once again there is a lot going on behind the scene as shown to the right.<br />
<a href="http://lh5.ggpht.com/-DwSaTJXHhv4/TwJpivFUDwI/AAAAAAAAAaY/XU3-7hww38M/s1600-h/Simple%252520Circles%252520-%252520Ninject.MVC3.png"><img align="right" alt="Simple Circles - Ninject.MVC3" border="0" height="181" src="http://lh5.ggpht.com/-pVHmm1sk_xU/TwJpi8JXKEI/AAAAAAAAAac/7wAVchovsMg/Simple%252520Circles%252520-%252520Ninject.MVC3_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; float: right; margin: 0px 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Ninject.MVC3" width="185" /></a>The <a href="https://github.com/ninject/ninject.web.mvc/wiki/MVC3" target="_blank">Ninject.MVC3 extension</a> was created to add support to MVC 3 applications including DI for Controllers, filters, validators and the Unit of Work pattern for NHibernate (more on this later!). The NuGet version adds a class to the \App_Start folder called NinjectMVC3 wired and ready to go. It does so by hooking in with the WebActivator project – one of the dependencies automatically installed when the Ninject.MVC3 package was installed.<br />
<h2>
Controller</h2>
First I’ll add references to the Domain and Persistence projects to bring in their type definitions then I’ll replace the EF context reference in PeopleController with the IPartyRepository instead. Refer to the last screenshot in the previous post to see the boilerplate code generated by the scaffolding.<br />
<pre class="c-sharp" name="code">public class PeopleController : Controller
{
private readonly IPartyRepository repository;
public PeopleController(IPartyRepository repository)
{
this.repository = repository;
}
public ViewResult Index()
{
IEnumerable<Domain.Person> persons = this.repository.FindAllPersons();
return View(persons);
}
...</pre>
<br />
The problem with the above code is that it will not compile because of line 13 – ‘<span style="font-family: 'Courier New';">return View(persons)</span>’. The MVC convention is to use separate model classes in the presentation layer to decouple it from the business/domain layer. I did exactly this when creating a Person class in the \Models folder - essentially flattening the <span style="font-family: 'Courier New', Courier, monospace;">EntityBase</span>-><span style="font-family: 'Courier New', Courier, monospace;">Entity</span>-><span style="font-family: 'Courier New', Courier, monospace;">Party</span>-><span style="font-family: 'Courier New', Courier, monospace;">Person</span> inheritance hierarchy to just <span style="font-family: 'Courier New', Courier, monospace;">Person</span>. The scaffolding constructed the views (Index, Details, Edit, etc.) to work with the <span style="font-family: 'Courier New', Courier, monospace;">Models.Person</span> class – not the <span style="font-family: 'Courier New', Courier, monospace;">Domain.Person</span>. Line 12 is returning an enumeration of <span style="font-family: 'Courier New', Courier, monospace;">Domain.Person</span> instances whereas the view expects <span style="font-family: 'Courier New', Courier, monospace;">Models.Person</span> instances.<br />
<br />
<h2>
Data Mapper</h2>
<br />
The solution to this mismatch lies in another tool called <a href="http://automapper.org/" target="_blank">AutoMapper</a> which makes using the <a href="http://martinfowler.com/eaaCatalog/dataMapper.html" target="_blank">Data Mapper</a> pattern a cinch. Jeremy Miller’s MSDN article <a href="http://msdn.microsoft.com/en-us/magazine/dd569757.aspx#id0400052" target="_blank">Persistence Patterns</a> gives a good overview of how these various proven patterns fit and work together. Also, Jimmy Bogard wrote a <a href="http://lostechies.com/jimmybogard/category/automapper/" target="_blank">series of articles</a> on his tool at Los Techies. Back to the NuGet Package Manager console to ‘<span style="font-family: 'Courier New';">Install-Package AutoMapper</span>’.<br />
<br />
I created a <span style="font-family: 'Courier New', Courier, monospace;">\Maps</span> folder and added a new class called <span style="font-family: 'Courier New', Courier, monospace;">PersonMap</span> to define the mapping back and forth between the two models…
<br />
<pre class="c-sharp" name="code">internal class PersonMap
{
internal static void CreateMaps()
{
Mapper.CreateMap<Domain.Person, Models.Person>()
.ForMember(dest => dest.Birthday, opt => opt.MapFrom(src => src.Birthday))
.ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
...
.ForMember(dest => dest.PersonId, opt => opt.MapFrom(src => src.PartyId))
.ForMember(dest => dest.FullName, opt => opt.MapFrom(src => src.PartyName))
.ForMember(dest => dest.Salutation, opt => opt.MapFrom(src => src.Salutation ?? null))
.ForMember(dest => dest.Suffix, opt => opt.MapFrom(src => src.Suffix ?? null));
Mapper.CreateMap<Models.Person, Domain.Person>()
.ForMember(dest => dest.ChannelAddresses, opt => opt.Ignore())
.ForMember(dest => dest.Birthday, opt => opt.MapFrom(src => src.Birthday))
.ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.FirstName))
...
.ForMember(dest => dest.PartyId, opt => opt.MapFrom(src => src.PersonId))
.ForMember(dest => dest.PartyName, opt => opt.Ignore())
.ForMember(dest => dest.PartyType, opt => opt.Ignore())
.ForMember(dest => dest.PostalAddresses, opt => opt.Ignore())
.ForMember(dest => dest.Salutation, opt => opt.MapFrom(src => src.Salutation ?? null))
.ForMember(dest => dest.Suffix, opt => opt.MapFrom(src => src.Suffix ?? null));
}
}</pre>
A few things are worth pointing out in the above listing:<br />
<ol><br />
<li>Line #9 shows how I map the generic, internal <span style="font-family: 'Courier New', Courier, monospace;">PartyId</span> from the domain model to the more friendly and meaningful <span style="font-family: 'Courier New', Courier, monospace;">PersonId</span> in the MVC layer. </li>
<li>Line #10 does the same for the <span style="font-family: 'Courier New', Courier, monospace;">PartyName</span> - mapping it to a <span style="font-family: 'Courier New', Courier, monospace;">FullName</span> property. </li>
<li>Line #15 tells the mapper to ignore the <span style="font-family: 'Courier New', Courier, monospace;">ChannelAddress</span> property in the domain model – it will not be mapped to the MVC layer. The same goes for <span style="font-family: 'Courier New', Courier, monospace;">PostalAddresses
</span> – these will be dealt with later and in a manner appropriate for the user interface.</li>
<li>Lines #11, #12, #23, #24 show how optional fields are handled.</li>
</ol>
<br />
A call to <span style="font-family: 'Courier New', Courier, monospace;">PersonMap.CreateMaps()</span> in <span style="font-family: 'Courier New', Courier, monospace;">Global.asax.cs</span> will initialize the maps when the website starts up. To use the maps, add a line to invoke the data mapping like this:<br />
<pre class="c-sharp" name="code">[HttpPost]
public ActionResult Create(Person person)
{
if (!ModelState.IsValid)
{
return View(person);
}
var entity = Mapper.Map<Person, Domain.Person>(person);
this.repository.Add(entity);
return RedirectToAction("Index");
}</pre>
<br />
Line #9 is the magic – transferring the contents of the MVC <span style="font-family: 'Courier New', Courier, monospace;">Models.Person</span> to the <span style="font-family: 'Courier New', Courier, monospace;">Domain.Person</span> before passing to the repository to store.<br />
<br />
<h2>
Dependency Injection</h2>
<br />
The <span style="font-family: 'Courier New', Courier, monospace;">PeopleController</span> at the top of this article used constructor injection on Line #5 to receive an <span style="font-family: 'Courier New', Courier, monospace;">IPartyRepository</span> instance. Following the Ninject samples and documentation, I’ve added a <span style="font-family: 'Courier New', Courier, monospace;">\Services\ServicesModule</span> which inherits from <span style="font-family: 'Courier New', Courier, monospace;">NinjectModule</span> to handle the injection of services:<br />
<pre class="c-sharp" name="code">/// <summary>
/// A Ninject module to bind services.
/// </summary>
public class ServicesModule : NinjectModule
{
/// <summary>
/// Called when the module loads into the kernel.
/// </summary>
public override void Load()
{
this.Bind<IPartyRepository>()
.To<FakePartyRepository>()
.InRequestScope();
}
}</pre>
<br />
To wire up the module, add a line to the RegisterServices method found in <span style="font-family: 'Courier New', Courier, monospace;">NinjectMVC3</span>:<br />
<pre class="c-sharp" name="code">private static void RegisterServices(IKernel kernel)
{
kernel.Load<Services.ServicesModule>();
}</pre>
<br />
The end result of this effort is that I can now browse and display the list of persons as shown here:<br />
<br />
<a href="http://lh5.ggpht.com/-2azF5zHQc44/TwJpjALedQI/AAAAAAAAAag/l4RTcZZ0PY4/s1600-h/Simple-Circles---MVC-with-Fake-Repo3.png"><img alt="Simple Circles - MVC with Fake Repo" border="0" height="227" src="http://lh6.ggpht.com/-T4H8QONKceY/TwJpjVj2bII/AAAAAAAAAak/2V5v4zscgsM/Simple-Circles---MVC-with-Fake-Repo_.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - MVC with Fake Repo" width="308" /></a><br />
<br />
Next time I’ll set up a unit test to exercise the functionality of the controller through injection so that I won’t have to always manually hit every view/page to see if it still works as changes are made.<br />
<br />
The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/b1ab47954e15" target="_blank">here</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-11971257785392259022012-01-11T18:39:00.000-05:002012-01-11T18:39:44.319-05:00Simple Circles–Add an ASP.NET MVC 3 UI (Part 4a)This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc.<br />
Last time I left off with a working fake implementation of the IPartyRepository called FakePartyRepository. We know that it is “working” because of the unit tests project that exercised the various methods of the contract. Since I have a working repository I’m going to start building out an ASP.NET MVC 3 website that will use the repository. My experience is that doing so earlier in the development cycle rather than later will flush out any problems or misaligned requirements. Remember, to this point I’ve been operating in something of a vacuum – building interfaces and implementations according to a vague vision of consuming them. Now I will make that vision concrete by constructing a user interface to work with.<br />
<h2>
Setup</h2>
Using the New Project wizard, I added an ASP.NET MVC 3 website and chose “Internet Application” for the template with Razor as the view engine. I <u>did not</u> elect to create unit tests as I’m using xUnit and the template support is not worth setting up according to <a href="http://xunit.codeplex.com/discussions/272171" target="_blank">this</a> discussion post. At this point pressing <F5> will bring up the default empty website.<br />
<a href="http://lh4.ggpht.com/-C33vsUmOiZ8/TwHS-sS09aI/AAAAAAAAAYs/-qcgmRT54T4/s1600-h/Simple-Circles---MVC-Scaffolding2.png"><img align="right" alt="Simple Circles - MVC Scaffolding" border="0" height="139" src="http://lh5.ggpht.com/-WD0dWewT6_M/TwHS-wWEQYI/AAAAAAAAAY0/lzTFRXaEL9I/Simple-Circles---MVC-Scaffolding_thu.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 0px 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - MVC Scaffolding" width="244" /></a>I’m a big fan of Steve Sanderson’s <a href="http://www.blogger.com/%3Ca%20href=%22http://www.amazon.com/gp/product/B005PZ07US/ref=as_li_qf_sp_asin_tl?ie=UTF8&tag=wsl-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B005PZ07US%22%3EPro%20ASP.NET%20MVC%203%20Framework%3C/a%3E%3Cimg%20src=%22http://www.assoc-amazon.com/e/ir?t=wsl-20&l=as2&o=1&a=B005PZ07US%22%20width=%221%22%20height=%221%22%20border=%220%22%20alt=%22%22%20style=%22border:none%20!important;%20margin:0px%20!important;%22%20/%3E" target="_blank">Pro ASP.NET MVC Framework</a> books as well as his work on the <a href="http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/" target="_blank">MVC Scaffolding</a> project which I started using last January as soon as he began publishing it. Therefore, I’m going to draw on his work to move things along quickly. First, I installed the scaffolding project using ‘<span style="font-family: 'Courier New';">install-package mvcscaffolding</span>’ which in turn brought in several dependencies as shown on the right.<br />
I’ll also start off simple by using <a href="http://go.microsoft.com/fwlink/?LinkID=103197" target="_blank">SQL Server Compact 4.0</a> along with the new <a href="http://nuget.org/packages/System.Web.Providers" target="_blank">ASP.NET Universal Providers 1.01</a>. You can follow <a href="http://www.hanselman.com/blog/IntroducingSystemWebProvidersASPNETUniversalProvidersForSessionMembershipRolesAndUserProfileOnSQLCompactAndSQLAzure.aspx" target="_blank">Scott Hanselman</a>’s or <a href="http://weblogs.asp.net/scottgu/archive/2011/01/11/vs-2010-sp1-and-sql-ce.aspx" target="_blank">Scott Guthrie</a>’s posts on setting it up.<br />
<h2>
Person</h2>
MVC Scaffolding works off a model so first I added a Person class to the Models folder…<br />
<pre class="c-sharp" name="code">namespace Circles.Models
{
using System;
using System.ComponentModel.DataAnnotations;
/// <summary>
/// Represents a view model of a Person
/// </summary>
public class Person
{
/// <summary>
/// Default constructor
/// </summary>
/// <remarks>Ensure Gender has a default value.</remarks>
public Person()
{
this.Gender = "Unknown";
}
[Display(Name = "Person Id")]
[Key]
public Guid PersonId { get; set; }
[Display(Name = "Full name")]
public string FullName { get; set; }
// [Required]
[Display(Name = "Salutation")]
[StringLength(20)]
public string Salutation { get; set; }
[Required]
[Display(Name = "First name")]
[StringLength(50, MinimumLength = 3)]
public string FirstName { get; set; }
...</pre>
<br />
<a href="http://lh6.ggpht.com/-djmdmAyjB6I/TwHS_JBQsPI/AAAAAAAAAY8/vSwiH5NkOEs/s1600-h/Simple%252520Circles%252520-%252520Scaffold%252520Person%25255B2%25255D.png"><img align="right" alt="Simple Circles - Scaffold Person" border="0" height="126" src="http://lh6.ggpht.com/-CTyH6tEfFus/TwHS_R3j3MI/AAAAAAAAAZE/U2NA1od-JrQ/Simple%252520Circles%252520-%252520Scaffold%252520Person_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 0px 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Scaffold Person" width="244" /></a>Now with a single NuGet instruction I scaffold a full CRUD interface for the model class using ‘<span style="font-family: 'Courier New';">scaffold controller PeopleController -ModelType Circles.Models.Person</span>’ as shown to the right. This one command generated an MVC controller class complete with all behaviors as well as a set of six Razor pages (Index to list, Details, Edit, Create, Delete, and a shared _CreateorEdit) to support CRUD behavior for a Person instance. As the second image shows, quite a bit of code was generated.<a href="http://lh3.ggpht.com/-Ovc9xGv254A/TwHS_euQjkI/AAAAAAAAAZM/jz8YV23iivQ/s1600-h/Simple%252520Circles%252520-%252520Scaffolded%252520Code%25255B2%25255D.png"><img align="right" alt="Simple Circles - Scaffolded Code" border="0" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5AXXx_O1Lwxcy2LY5LtFAIwS31-jglXRWHXj8YNEGc3ivISDcY1DhgEyWqG2xmt7y6ii0IbGCsBvv1gvuHdlArI7CZWr_aslRkNHx7Q8lF4a7Y5D60DxPdOBpUhx3ZlGgiDxBrqHkimek/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin: 5px 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Scaffolded Code" width="244" /></a><br />
<br />
I can’t say enough about how exceedingly cool Steve’s scaffolding work is and how much effort it saves. Unfortunately, the current implementation is built to support Entity Framework as the underlying data technology. Notice the <span style="font-family: 'Courier New';">CirclesContext</span> class added to the Models folder and the reference to that context embedded in the <span style="font-family: 'Courier New';">PeopleController</span> class. While the hooks are there to plug in other scaffolding templates (e.g. NHibernate) as of yet nobody has stepped forward to provide implementations.<br />
<br />
You could also, as Steve suggests, add the Entity Framework 4.1 Code First capability via ‘<span style="font-family: 'Courier New';">install-package EFCodeFirst.SqlServerCompact</span>’ then regenerate the controller with the additional flags ‘<span style="font-family: 'Courier New';">-Repository –Force</span>’. You’d then have a working repository-based implementation built with all Microsoft products.<br />
<br />
In the second part of this installment I’ll take a different approach and wire in Ninject as the dependency injection framework then use it to inject the FakePartyRepository previously built.<br />
<br />
The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/1e517954dc75" target="_blank">here</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-7643870600543673822012-01-09T06:00:00.000-05:002012-01-09T06:00:11.706-05:00Simple Circles–Fake Repository (Part 3)<p>This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc. With a basic structure for the domain objects taking shape it’s time to move on to the notion of persistence.</p> <p>In the last post I set up the interfaces to support the Repository pattern and left off with the following signature:</p><pre class="c-sharp" name="code">namespace Circles.Persistence<br />{<br /> using System;<br /> using System.Linq;<br /><br /> public interface IPartyRepository : IRepository<Party, Guid>, ISupportSave<Party, Guid>, ISupportDelete<Party, Guid><br /> {<br /> IQueryable<Household> FindAllHouseholds();<br /> IQueryable<Organization> FindAllOrganizations();<br /> IQueryable<Person> FindAllPersons();<br /> }<br /></pre><br /><p>Now I’m going to put together a simple fake repository implementation to exercise the interfaces as well as quickly provide sample data to work with. I’ve added a new project called FakeRepository containing a single class called FakePartyRepository partly shown here:</p><pre class="c-sharp" name="code">namespace Circles.FakeRepository<br />{<br /> using System;<br /> using System.Collections.Generic;<br /> using System.Linq;<br /><br /> public class FakePartyRepository : IPartyRepository<br /> {<br /> private readonly List<Household> fakeHouseholdList = new List<Household> <br /> {<br /> new Household { PartyName = "Churchill", FormalGreeting = "Sir Winston and Lady Clementine" },<br /> new Household { PartyName = "Roosevelt", FormalGreeting = "President Franklin and Mrs. Eleanor" },<br /> };<br /><br /> private readonly List<Organization> fakeOrganizationList = new List<Organization> <br /> {<br /> new Organization { PartyName = "Great Lakes Food Market" },<br /> new Organization { PartyName = "Hungry Coyote Import Store" },<br /> new Organization { PartyName = "Lazy K Kountry Store" },<br /> };<br /><br /> private readonly List<Person> fakePersonList = new List<Person><br /> {<br /> new Person { FirstName = "Nancy", LastName = "Davolio", Gender = GenderEnum.Female, Birthday = new DateTime(1948, 12, 8) },<br /> new Person { FirstName = "Andrew", LastName = "Fuller", Gender = GenderEnum.Male, Birthday = new DateTime(1992, 8, 14) },<br /> };<br /><br /> private readonly IQueryable<Household> fakeHouseholdRepository;<br /> private readonly IQueryable<Organization> fakeOrganizationRepository;<br /> private readonly IQueryable<Person> fakePersonRepository;<br /> private readonly IQueryable<Party> fakePartyRepository;<br /><br /> public FakePartyRepository()<br /> {<br /> this.fakeHouseholdRepository = this.fakeHouseholdList.AsQueryable();<br /> this.fakeOrganizationRepository = this.fakeOrganizationList.AsQueryable();<br /> this.fakePersonRepository = this.fakePersonList.AsQueryable();<br /> this.fakePartyRepository = this.fakeOrganizationList.Union<party>(this.fakePersonList).Union(this.fakeHouseholdList).AsQueryable();<br /> }<br /><br /> public IQueryable<Party> FindAll()<br /> {<br /> return this.fakePartyRepository;<br /> }<br /><br /> public Party FindById(Guid id)<br /> {<br /> return this.fakePartyRepository.FirstOrDefault(x => x.PartyId == id);<br /> }<br /> }<br /></pre><br /><p>As you can see, the underlying data is contained in simple in-memory generic Lists that are wrapped into LINQ IQueryable objects. Note the last line of the constructor where the fakePartyRepository is a .Union of the three underlying lists.</p><br /><p><a href="http://lh5.ggpht.com/-pGYdwMCzf64/TwEO9mflxcI/AAAAAAAAAYM/EJioYs4dFPE/s1600-h/Simple%252520Circles%252520-%252520xunit%25255B2%25255D.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Simple Circles - xunit" border="0" alt="Simple Circles - xunit" align="right" src="http://lh4.ggpht.com/-oIZQygx-F9k/TwEO__vv5JI/AAAAAAAAAYU/6fiOBNnCIcI/Simple%252520Circles%252520-%252520xunit_thumb.png?imgmax=800" width="244" height="101"></a>To test the FakeRepository let’s add another class library project called UnitTests. We’ll use <a href="http://nuget.org/" target="_blank">NuGet</a> to add the <a href="http://xunit.codeplex.com/" target="_blank">xUnit</a> package with the command ‘<font face="Courier New">install-package xunit</font>’ as shown to the right. xUnit was created by James Newkirk (creator of the venerable NUnit) and Brad Wilson to better reflect the purpose of driving and iterating the design of an implementation at the unit level. Brad discusses this philosophy in his article <a href="http://bradwilson.typepad.com/blog/2009/04/its-not-tdd-its-design-by-example.html" target="_blank">Its not TDD, It’s Design by Example</a>. After adding the xUnit reference, add a class called PartyRepositoryTest:</p><pre class="c-sharp" name="code"> public class PartyRepositoryTest<br /> {<br /> [Fact]<br /> public void CanAddHousehold()<br /> {<br /> // arrange<br /> IPartyRepository repository = new FakePartyRepository();<br /><br /> // act<br /> var id = repository.Add(new Household<br /> {<br /> PartyName = "Eisenhower", <br /> FormalGreeting = "President Dwight D. and Mrs. Mamie", <br /> InformalGreeting = "Ike and Mamie"<br /> });<br /><br /> // assert<br /> Assert.NotNull(id);<br /> Assert.NotNull(repository.FindById(id));<br /> }<br /> }<br /></pre><br /><p>The first thing you may notice is that xUnit uses the attribute [Fact] rather than [Test] as other TDD frameworks do. As Brad puts it “a [Fact] is an expression of some condition which is invariant”. Essentially we’re saying that the condition “<em>CanAddHousehold</em>” is an invariant condition of the PartyRepository which must always be true. In addition to expressing facts, xUnit lets you express theories which are “an expression of a condition which is only necessarily true for the given set of data.”:</p><pre class="c-sharp" name="code"> [Theory,<br /> InlineData("D28AA45E-C650-4121-8070-3D12BE31F91A")]<br /> public void CanFindSinglePerson(string id)<br /> {<br /> // arrange<br /> IPartyRepository repository = new FakePartyRepository();<br /> var partyId = new Guid(id);<br /><br /> // act<br /> var person = repository.FindById(partyId) as Person;<br /><br /> // assert<br /> Assert.NotNull(person);<br /> Assert.True(person.Id == partyId);<br /> }<br /></pre><br /><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgMirzxmOpsQ7KlrAGZIFSAbL6nURsFobo60MlNTWoNPqIgkxVM0k8c_svtrHto11w5ZSLiNbU7_aEIovclgRqkndPzdcIqUwzeApDlwavt6t6-fnKKpEBVfRa-6kEN8EoMWedVNUGZKD1/s1600-h/Simple%252520Circles%252520-%252520Unit%252520Tests%25255B2%25255D.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Simple Circles - Unit Tests" border="0" alt="Simple Circles - Unit Tests" align="right" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7PDy_4JAxt0q0PhLpZ8ZHKsAfBAGgz-_31N2uMt3NhgfdfDt5jpO6TuUkfJGI2D8suA_hZIblFa8Z3vu1vW7UQ4NgAnDRBeFSDqPNxF-wtUOqo4Bs_pxKDv8t0uKVU7G4dIAvHkTESV5E/?imgmax=800" width="214" height="244"></a>Since we built the FakeRepository with our known data, we can construct tests with known values to prove the repository is working as designed without defects. In the above example, we know the PartyId of one of the person instances that we put into the fake repository so we can attempt to retrieve that person to exercise that logic. <a href="http://www.jetbrains.com/resharper/" target="_blank">ReSharper</a>’s test runner shows all the tests we currently have. Before the tests can be compiled and run, you must add a reference to the Extensions subproject of xUnit which holds the [Theory] attribute definition and behavior. Once again, use the NuGet Package Manager Console to execute the command “<font face="Courier New">install-package xunit.extensions</font>”.</p><br /><p>Finally, you’ll notice in the above samples as well as the source code accompanying this post that I’ve followed the “3A” or “<a href="http://c2.com/cgi/wiki?ArrangeActAssert" target="_blank">Arrange-Act-Assert</a>” principle for writing the tests.</p><br /><p>The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/057ff59f7d5b" target="_blank">here</a>.</p><br /><p>Next we’ll look at starting an ASP.NET MVC 3 website to consume and present the domain model.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-50516960924725225592012-01-04T22:26:00.000-05:002012-01-04T22:26:26.866-05:00Simple Circles–Persistence (Part 2)This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc. With a basic structure for the domain objects taking shape it’s time to move on to the notion of persistence.<br />
One of the tenets of <a href="http://domaindrivendesign.org/resources/what_is_ddd" target="_blank">DDD</a> is known as “aggregate root” – a top-level, course grained collection of responsibilities. In plain object-oriented systems, objects tend to expose granular methods to operate on their data. Unfortunately, this approach allows business knowledge and intimate design details to creep outside of the model. That is, accomplishing a business operation usually entails making several method calls across several objects – this sequencing of calls becomes embedded externally in calling applications making the whole thing tightly coupled and brittle. The aggregate root principle groups related objects closely and provides consistent and coordinated access to these related objects.Vaughn Vernon wrote an in depth three-part article on the topic of <a href="http://domaindrivendesign.org/library/vernon_2011" target="_blank">Effective Aggregate Design</a>.<br />
In this model the Party is an obvious root object – we don’t access addresses or notes without first going through the Party instance they belong to. This approach leads to methods like Party.AddAddress() or Party.AddNote() rather than creating addresses and notes separately.<br />
Once the aggregate root(s) have been identified it’s time to move on to persisting the data they contain. The Repository pattern is a proven way to implement persistence in a storage-neutral manner. There are many references to consult for more information but in the context of DDD, Jak Charlton’s post, <a href="http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx" target="_blank">DDD: The Repository Pattern</a>, is particularly concise and a good starting point for why it is useful. Gabriel Schenker provides another good <a href="http://nhibernate.hibernatingrhinos.com/27/the-repository-pattern" target="_blank">write up</a> with code examples on the NHibernate FAQ. Given that we have a Party aggregate root, we should also have a PartyRepository since each aggregate should be responsible for its own “domain” or “scope” if you will.<br />
Since repositories manage aggregate roots and their associated entities/ values, the basic semantics for the repository follow that of a generic collection. For us this means something like:<br />
<pre class="c-sharp" name="code">namespace Circles.Persistence
{
using System;
using System.Collections.Generic;
public interface IPartyRepository
{
IList<Party> FindAllParties();
Party FindPartyById(Guid Id);
Guid Add(Party party);
void Delete(Guid Id);
void Update(Party party);
}
}</pre>
<br />
Some might balk at the Delete and Update methods, arguing that pure collections have “Remove” instead. However, I am of the opinion that we’re working with domain (a.k.a. business) entities that are persisted <em>somewhere</em> so the semantics of persisting data are more natural with delete and update.<br />
<br />
Of course the above approach is very "party-specific” so it could be refactored using generics like this:<br />
<pre class="c-sharp" name="code">namespace Circles.Persistence
{
using System;
using System.Collections.Generic;
public interface IRepository<T> where T : Entity
{
IList<T> FindAll();
T FindById(Guid Id);
Guid Add(T entity);
void Delete(Guid Id);
void Update(T entity);
}
}</pre>
<br />
Now we’ve got an interface that supports any type of domain entity – note the removal of the term “Party” from the method names.<br />
<br />
The above refactored interface implies that every repository created supports all four “CRUD” operations. A better approach would be to split out the operations and then have a specific repository implement the ones it needs like this:<br />
<pre class="c-sharp" name="code">namespace Circles.Persistence
{
using System;
using System.Linq;
public interface IRepository<T, in TId> where T : Entity
{
T this[TId id] { get; set; }
IQueryable<T> FindAll();
T FindById(TId Id);
}
public interface ISupportSave<in T, out TId> where T : Entity
{
TId Add(T entity);
void Update(T entity);
}
public interface ISupportDelete<T, in TId> where T : Entity
{
void Delete(TId Id);
}
public interface IPartyRepository : IRepository<Party, Guid>, ISupportSave<Party, Guid>, ISupportDelete<Party, Guid>
{
IQueryable<Household> FindAllHouseholds();
IQueryable<Organization> FindAllOrganizations();
IQueryable<Person> FindAllPersons();
}</pre>
<br />
Now we’re explicit about what the PartyRepository does. By implementing IRepository, ISupportSave and ISupportDelete we’re clear that the IPartyRepository supports full CRUD behavior using Guids for the Id types. Additionally, we provide FindAllxxx methods for retrieving specific types from the repository. Notice that having the repository return IQueryable gives flexibility on both sides – concrete implementations can translate the LINQ query passing it to the underlying data store for execution and callers can query the repository in various ways rather than being forced to go through a rigid, narrowly defined API we provide.<br />
<br />
One more thing to cover – I slipped in a new Type called Entity that is a base class for all domain entities. Rather than rehashing all the details here I’d suggest checking out Jason Dentler’s <a href="http://www.jasondentler.com/blog/" target="_blank">blog</a> or his book <a href="http://www.blogger.com/%3Ca%20href=%22http://www.amazon.com/gp/product/184951304X/ref=as_li_tf_tl?ie=UTF8&tag=wsl-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=184951304X%22%3ENHibernate%203.0%20Cookbook%3C/a%3E%3Cimg%20src=%22http://www.assoc-amazon.com/e/ir?t=wsl-20&l=as2&o=1&a=184951304X%22%20width=%221%22%20height=%221%22%20border=%220%22%20alt=%22%22%20style=%22border:none%20!important;%20margin:0px%20!important;%22%20/%3E" target="_blank">NHibernate 3.0 Cookbook</a>. Equally important is Billy McCafferty’s work on <a href="https://github.com/sharparchitecture/sharp-architecture" target="_blank">Sharp Architecture</a>. Standing on the shoulder’s of giants…<br />
<br />
The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/c1f3115cfdf3" target="_blank">here</a>.<br />
<br />
Next we’ll look at testing what we have xUnit.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-50380814165108730712012-01-03T05:44:00.000-05:002012-01-03T05:46:11.130-05:00Simple Circles–Domain Model (Part 1)This post is part of a <a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesintroduction.html">series</a> on building a simple to use web-based contact and customer relationship management application. The goal is to support various audiences including businesses, teams, clubs, religious organizations, etc. Thus, it is important that the domain model be flexible enough to allow various combinations of entities to be used to support these use cases. For example, in a <a href="http://en.wikipedia.org/wiki/Business-to-business" target="_blank">B2B</a> scenario the notion of a person or a household will not likely be center stage whereas businesses will be. However, a club or sports team will likely interact with individuals and possibly households but not likely with businesses.<br />
<h2>
Models</h2>
<a href="http://lh4.ggpht.com/-b9oMCUMbNMM/TwEIhWFRpQI/AAAAAAAAAXs/wEhns3KOC1c/s1600-h/Simple-Circles---Party-Concept2.png"><img align="right" alt="Simple Circles - Party Concept" border="0" height="200" src="http://lh6.ggpht.com/-5-jU3nWNjug/TwEIhyT5ifI/AAAAAAAAAX0/CNvrvidoV60/Simple-Circles---Party-Concept_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin-bottom: 0px; margin-left: 5px; margin-right: 0px; margin-top: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Party Concept" width="190" /></a>Modeling entities such as Person, Household, and Organization come to mind immediately. However, the “Party” model has existed for many years as a way to generically model the relationships between various parties. The figure to the right illustrates graphically this concept. Person, Household, and Organization are all types of parties. This approach also allows reuse of relationships such as notes, postal addresses, and communication channels across all types of parties. Rather that duplicating logic, storage mechanisms and business rules for each entity this approach follows the Don’t Repeat Yourself (<a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself" target="_blank">DRY</a>) principle.<br />
<br />
<a href="http://lh3.ggpht.com/-YY_yLzvY93k/TwEIiFPxutI/AAAAAAAAAX4/susTbkORwlI/s1600-h/Simple-Circles---Party-Class-Diagram%25255B1%25255D.png"><img align="right" alt="Simple Circles - Party Class Diagram" border="0" height="134" src="http://lh6.ggpht.com/-HmUplfjbC_Q/TwEIitICT-I/AAAAAAAAAYA/N1KKkcV_pAs/Simple-Circles---Party-Class-Diagram.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; float: right; margin-bottom: 0px; margin-left: 5px; margin-right: 0px; margin-top: 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Simple Circles - Party Class Diagram" width="200" /></a>Transferring the conceptual model to a physical one is accomplished using inheritance as shown in the class diagram to the right. The Party class is an abstract base class containing a PartyId unique identifier and a PartyName. Person, Household, and Organization all inherit these base properties supplementing them with specific properties they contain. Notice that the base class contains relationships to Party Note, Postal Address and Channel Address as well as to Party Type. Through inheritance all child subtypes also inherit these relationships without having to explicitly code them three different times (DRY!). Using a separate Party Type allows classifying individual party instances which supports filtering the parties in lists, views, etc.<br />
<h2>
Classes</h2>
Here is the code for the Party class which realizes the class diagram shown above:<br />
<pre class="c-sharp" name="code">namespace Circles.DomainModel
{
using System;
using System.Collections.Generic;
/// <summary>
/// An abstract class representing any 'Party' that can be interacted with.
/// </summary>
public abstract class Party
{
private ISet<ChannelAddress> channelAddresses = new HashSet<ChannelAddress>();
private ISet<PartyNote> notes = new HashSet<PartyNote>();
private ISet<PostalAddress> postalAddresses = new HashSet<PostalAddress>();
/// <summary>
/// Gets or sets the unique identifier of the Party instance.
/// </summary>
public Guid PartyId { get; set; }
/// <summary>
/// Gets or sets the name of the Party instance.
/// </summary>
public virtual string PartyName { get; set; }
/// <summary>
/// Gets or sets the PartyType of the Party instance.
/// </summary>
public virtual PartyType PartyType { get; set; }
/// <summary>
/// Gets or sets the Notes associated with the Party instance.
/// </summary>
public ISet<ChannelAddress> ChannelAddresses
{
get { return this.channelAddresses; }
set { this.channelAddresses = value; }
}
/// <summary>
/// Gets or sets the Notes associated with the Party instance.
/// </summary>
public ISet<PartyNote> Notes
{
get { return this.notes; }
set { this.notes = value; }
}
/// <summary>
/// Gets or sets the Notes associated with the Party instance.
/// </summary>
public ISet<PostalAddress> PostalAddresses
{
get { return this.postalAddresses; }
set { this.postalAddresses = value; }
}
}
}</pre>
<br />
Note that this is not the “finished product” but rather an early version along the way. Future articles will refine this further.<br />
<br />
The source code for this article can be downloaded from <a href="http://simplecircles.codeplex.com/SourceControl/changeset/changes/0e3454db36be#" target="_blank">here</a>.<br />
<br />
Next we’ll look at persistence of this model.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-53748913296578372012012-01-01T06:00:00.000-05:002012-02-19T22:33:26.903-05:00Simple Circles–Introduction<div dir="ltr" style="text-align: left;" trbidi="on">
This series will be a step-by-step approach on building a simple to use web-based contact and customer relationship management application. The goals are to employ current best practices including domain-driven design (<a href="http://domaindrivendesign.org/resources/what_is_ddd" target="_blank">DDD</a>), object-relational mapping (<a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank">ORM</a>), unit testing – a <a href="http://en.wikipedia.org/wiki/Unit_testing" target="_blank">component</a> of Test-Driven Development (TDD), and the model-view-controller paradigm of <a href="http://www.asp.net/mvc/mvc3" target="_blank">ASP.NET MVC3</a>. Additionally, as the name suggests – the finished product must be simple to use. While patterns, practices and techniques employed to build the application might be advanced the end user mustn't be overwhelmed. Keeping track of a circle of friends, acquaintances and associates should be simple!<br />
There are numerous examples of using these practices and technologies around the Internet. However many are overly simplified – designed to show a particular technique – rather than a complete “real world” example. Technical books tend to stick to the Microsoft mantra of always using their latest offering or their shiny new version of some proven OSS product. For example, Steve Sanderson’s Sports Store in <a href="http://www.blogger.com/%3Ca%20href=%22http://www.amazon.com/gp/product/1430234040/ref=as_li_qf_sp_asin_tl?ie=UTF8&tag=wsl-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1430234040%22%3EPro%20ASP.NET%20MVC%203%20Framework%3C/a%3E%3Cimg%20src=%22http://www.assoc-amazon.com/e/ir?t=wsl-20&l=as2&o=1&a=1430234040%22%20width=%221%22%20height=%221%22%20border=%220%22%20alt=%22%22%20style=%22border:none%20%21important;%20margin:0px%20%21important;%22%20/%3E" target="_blank">Pro ASP.NET MVC 3 Framework</a> and Tim McCarthy’s <a href="http://www.blogger.com/%3Ca%20href=%22http://www.amazon.com/gp/product/0470147563/ref=as_li_tf_tl?ie=UTF8&tag=wsl-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0470147563%22%3E.NET%20Domain-Driven%20Design%20with%20C#:%20Problem%20-%20Design%20-%20Solution%20%28Programmer%20to%20Programmer%29%3C/a%3E%3Cimg%20src=%22http://www.assoc-amazon.com/e/ir?t=wsl-20&l=as2&o=1&a=0470147563%22%20width=%221%22%20height=%221%22%20border=%220%22%20alt=%22%22%20style=%22border:none%20%21important;%20margin:0px%20%21important;%22%20/%3E" target="_blank">SmartCA in .NET Domain-Drive Design with C#</a> both deliver complete examples yet neither tackle NHibernate. That is, true persistence ignorance beyond the theory that its possible. Don’t misunderstand, I’m not saying they’re bad books – I’ve bought both, used them to learn, and do refer back to them. However, if I see another contrived example of using Entity Framework with a few wizards to whip out a solution I’ll scream. <img alt="Smile" class="wlEmoticon wlEmoticon-smile" src="http://lh4.ggpht.com/-dAnXvtxxsnU/TwBkMaWmt2I/AAAAAAAAAXk/OXP-APzldQU/wlEmoticon-smile%25255B2%25255D.png?imgmax=800" style="border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;" /><br />
This application will be built with NET 4.0 using the following tools and technologies:<br />
<ol>
<li><a href="http://www.microsoft.com/visualstudio/en-us" target="_blank">Visual Studio 2010</a> with <a href="http://nuget.org/" target="_blank">NuGet</a> package support </li>
<li><a href="http://www.asp.net/mvc/mvc3" target="_blank">ASP.NET MVC 3</a> and Razor view engine </li>
<li>Persistence layer will be: <ol style="list-style-type: lower-alpha;">
<li><a href="http://nhforge.org/" target="_blank">NHibernate 3.1</a> with <a href="http://www.sqlite.org/" target="_blank">SQLite</a> </li>
<li><a href="http://msdn.microsoft.com/en-us/data/aa937723" target="_blank">Entity Framework 4.1</a> with <a href="http://www.microsoft.com/sqlserver/en/us/editions/compact.aspx" target="_blank">SQL Server CE 4.0</a></li>
</ol>
</li>
<li><a href="http://ninject.org/" target="_blank">Ninject 2.2</a> for dependency injection </li>
<li><a href="http://xunit.codeplex.com/" target="_blank">xUnit</a> for unit testing</li>
<li><a href="http://jqueryui.com/" target="_blank">jQuery UI</a> for user experience. </li>
</ol>
Here are links to the posts for this project:<br />
<ol>
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesdomain-model-part-1.html">Domain Model</a></li>
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlespersistence-part-2.html" target="_blank">Persistence</a></li>
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesfake-repository-part-3.html">Fake Repository</a></li>
<li>ASP.NET MVC 3 UI
<ol style="list-style-type: lower-alpha;">
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesadd-aspnet-mvc-3-ui-part.html">Scaffold People CRUD</a></li>
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesadd-aspnet-mvc-3-ui-part_15.html">Replace EF hard wiring with Repository pattern</a></li>
</ol>
</li>
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesmvc-controller-unit-tests.html">MVC Controller Unit Tests</a></li>
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesenabling-jquery-ui-part-6.html">Enabling jQuery UI</a> </li>
<li>NHibernate Repository
<ol style="list-style-type: lower-alpha;">
<li><a href="http://pragmatic-software.blogspot.com/2012/01/simple-circlesnhibernate-repository.html">IDbSession and implementation</a></li>
<li><a href="http://pragmatic-software.blogspot.com/2012/02/simple-circlesnhibernate-mapping-part.html">Fluent NHibernate mapping</a></li>
<li><a href="http://pragmatic-software.blogspot.com/2012/02/simple-circlesnhibernate-unit-testing.html">NHibernate Unit Testing</a></li>
</ol>
</li>
</ol>
As this series is developed, I’ll keep updating this post with new links.
</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-33038653635976523862011-04-15T22:09:00.001-04:002011-04-15T22:09:23.138-04:00First Foray into Windows Home Server (WHS)<p>I just inherited an <a href="http://h10025.www1.hp.com/ewfrf/wc/product?product=3855978" target="_blank">HP EX485 MediaSmart Server</a> in near new condition. First impression is that it is <em><strong>*tiny*</strong></em> — about as tall as a college textbook standing on edge and six inches wide. WHS machines are network-ready, do not have a VGA output nor display adapter and typically have multiple drive bays designed for adding low cost serial ATA (SATA) drives as storage needs grow. <a href="http://lh3.ggpht.com/_BvH8o_BvG-4/Taj6R8yb28I/AAAAAAAAAXE/E2AJLmYaMig/s1600-h/system_disk%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="system_disk" border="0" alt="system_disk" align="right" src="http://lh3.ggpht.com/_BvH8o_BvG-4/Taj6SINysmI/AAAAAAAAAXI/KZr4TN7c08Y/system_disk_thumb.png?imgmax=800" width="244" height="40"></a>The EX485 comes with a single 750 GB drive partitioned with a small 20 GB system (“C:\”) and the remainder as a large “D:\” data drive.The <a href="http://h10025.www1.hp.com/ewfrf/wc/document?docname=c01586299#c86299d" target="_blank">specifications</a> state that fully loaded with four drives it will consume a paltry 76 watts of power! </p> <p>WHS is an interesting, strange brew – a fully-functioning Windows server product with an easy to use setup and interface sold only to OEMs. The intention is to provide something dead-simple to setup that consumers can take home, plug-in and it just works. Scott Hanselman wrote a nice introductory review of WHS and the MediaSmart <a href="http://www.hanselman.com/blog/ReviewHPMediaSmartWindowsHomeServer.aspx" target="_blank">here</a>. As the name suggests, the EX485 is designed to store and serve media – movies, music and photos.</p> <p><a href="http://lh3.ggpht.com/_BvH8o_BvG-4/Taj6SzXvecI/AAAAAAAAAXM/9oAZaMa9drM/s1600-h/whs_console%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="whs_console" border="0" alt="whs_console" align="right" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNHpBsoWr6OXhD8QkxwflKFTAflmhh1ERLQiMjZlG9l13xivgXTaAeCIN5fkZEIPUDzy7rDaNMES06T9-pg1k4eT4pSa5RWOrLM2aiiUYeoH9yDgwPfE-mjVad8KJ5xZWXTy4CYHMm7Gp1/?imgmax=800" width="244" height="173"></a>Under the covers WHS v1 is Windows Server 2003 so it’s a solid and reliable server platform. It exposes a user-friendly console that OEMs can extend to provide functionality as shown here. Notice the small link indicated in the upper right that opens a settings panel where you can configure the server – again the dialog is extensible by OEMs.</p> <p><a href="http://lh5.ggpht.com/_BvH8o_BvG-4/Taj6Tt5m10I/AAAAAAAAAXU/3MVi-4REyic/s1600-h/whs_upnp%5B3%5D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="whs_upnp" border="0" alt="whs_upnp" align="left" src="http://lh3.ggpht.com/_BvH8o_BvG-4/Taj6UF26K0I/AAAAAAAAAXY/Fra5mWWlt7w/whs_upnp_thumb%5B1%5D.png?imgmax=800" width="201" height="170"></a>WHS supports universal plug and play (UPnP) so other machines in your home network can discover and access it. From there you can install a client “connector” that gives you access to the console shown above. Connecting a client machine is sort of like an ultra-light version of joining a domain without the intrusive “taking over”.</p> <p>Client computers will get a “Shared Folders” link on their desktop that shows all the pre-configured shares (e.g. Documents, Music, Photos, Videos) on the server as well as any custom ones you’ve added. A “Windows Home Server Connector Service” will be installed along with a system tray icon and nightly backups will be configured.</p> <p><a href="http://lh5.ggpht.com/_BvH8o_BvG-4/Taj6URtzieI/AAAAAAAAAXc/sXMNnBsZfgA/s1600-h/ex485_server%5B2%5D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top: 0px; border-right: 0px; padding-top: 0px" title="ex485_server" border="0" alt="ex485_server" align="left" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5cvNq3GPsr9nJ0EqfYmwsg59DXsZyaLnTDCc9ffg29Yqt6_S9epdd1f66PP0cvB5rCTiwbSh16pLSmu0dDdxEgym0glu_0jJO32jbR-8i2FgsoIVYSS2EnITN64qxXs70aUfsWIXd-obj/?imgmax=800" width="244" height="199"></a>Windows Home Server 2011 (a.k.a. v2) was released a couple of weeks ago. While articles are popping up that show how to wipe the existing v1 and install the shiny new toy I’m going to stay put. I’m currently running HP MediaSmart Server v2.5.15.35297 which was released in April 2009. The system shipped with this configuration and it’s got the latest patches and updates. I expect to be running this until the hardware fails or becomes so outdated that it becomes compelling to update to a newer platform.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-45275992297470158722010-12-24T06:00:00.002-05:002010-12-24T06:00:08.172-05:00How To Build an ASP.NET 4.0 Web Service and Consume It With Excel 2007-Part 2With a freshly built web service we can now have a bit of fun.<br />
<ol><li>Create a new project utilizing the Visual Studio Tools for Office template for <b><i>Excel 2007 Workbook</i></b>:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjBgzqwaI/AAAAAAAAAUI/cRtnaqva2Nc/s1600-h/2010-12-05_091921%5B2%5D.png"><img alt="2010-12-05_091921" border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKrcAd3YUCiM1dDZ4T2glYouNmzzEgvv1xKttOgDMTMDjsJ4on2yZiJk4mNEKC40Fdj7jLqZnHu7d9rmSMgTEPw51D_A1wYoTfLxqhV7C_3AxBwtyHr4XMqTIu1Y2CCwuHlpQk4YAL2XEw/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_091921" width="244" /></a><br />
</li>
<li>Accept the default settings for <b><i>Create a new document</i></b> and click OK:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TRAjCNO9F-I/AAAAAAAAAUQ/uBXmXgPo2tc/s1600-h/2010-12-05_091937%5B2%5D.png"><img alt="2010-12-05_091937" border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtkDo6TjWs0NxQ_DBVBaXrBMPbGTtClOoorotGJ5hDjDOMwqGBm3EC0bH0bGilbGWFhV-YOc1_zI9F8zslqKWvmeYdgK8WwZpVzude6yZ7-mzOViujXPRmaIpftCUlM00qPC914dGwMaKn/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_091937" width="244" /></a><br />
Note: if you encounter errors while creating a new project it is most likely because the VSTO add-ins are not configured until first used.<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrcFhNrEI_Vs2XCzZ6FeQRq8FCGRQg9_NtGDjNFpCSHYvyxECgJrLEloC7xgpT0ykRfXiZE8En855Vo6ROXOfMuxjZMlkgEP8yrUY5W8V8AVRCCSL9HYMyix1TnGvFruekXdIjskMakC8O/s1600-h/2010-12-05_091947%5B2%5D.png"><img alt="2010-12-05_091947" border="0" height="134" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TRAjCzJqJqI/AAAAAAAAAUc/40Nn80PDMMU/2010-12-05_091947_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_091947" width="244" /></a><br />
The quickest way to resolve the issue is to exit out of Visual Studio and use the right-click <b><i>Run as administrator</i></b> trick to launch with elevated permissions.<br />
</li>
<li>From the Solution Explorer, right-click on the <b><i>References</i></b> folder then choose <strong><em>Add Service Reference</em></strong>:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpHoD0xI1bn64Z7OsqsWo220V-Fqd6GL6XMkctfNUxal-I8rhwH3yIJqkL0H7qnyDWu21dP2JGaueUZtRd5t4qzIWcRWpcHF-GjoiKn-lcJ5SwmnX9myGxzHccLqbdK_ov2KLCDSvJD9yO/s1600-h/2010-12-05_092357%5B2%5D.png"><img alt="2010-12-05_092357" border="0" height="117" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjDHJceDI/AAAAAAAAAUk/bHrc-z_FeO4/2010-12-05_092357_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_092357" width="244" /></a><br />
</li>
<li>Type in the web address of the web service we just created:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8Nt9R8qXD26PQXj2RBBLWJie0fV3WFav5OaaXUJ_rgTQ9F10x6GR0U2EJuuXo927k63vqsF_76Y7tEUKpAxOmtVAGFaLnjBV9o0N5JqhNJxtK794zfF97dLwAx2aKCPujHgkXJ3AUn2hT/s1600-h/2010-12-05_092441%5B2%5D.png"><img alt="2010-12-05_092441" border="0" height="71" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjDqJK1lI/AAAAAAAAAUs/jnBoHjEDj0g/2010-12-05_092441_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_092441" width="244" /></a><br />
Hint: You may want to switch (Alt-Tab) over to the browser window where we tested the web service against IIS after deploying then copy the address from the address bar.<br />
</li>
<li>After pressing <strong>Go</strong> the deployed web service will be queried and the results displayed for confirmation:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZC0JtLtRPgXFiXT7fC5kl1RgGT7750l36cQZiC5vsCGnJm_nOYsV0b8MwRI8ZbwEJ3xirLRjSCG43JL64NjGQ6NnHQ5FehmDrczyBD-7SWmmEwFnVii3_K8_0FRB3nFjsdj0ifpwmHGv8/s1600-h/2010-12-05_092507%5B2%5D.png"><img alt="2010-12-05_092507" border="0" height="198" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TRAjEIh_jOI/AAAAAAAAAU0/rUmugyrnqTY/2010-12-05_092507_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_092507" width="244" /></a><br />
</li>
<li>With the Excel Workbook Designer displayed from within Visual Studio right-click anywhere on the worksheet and choose <b><i>View Code</i></b>:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFY0mmtoYcL2otMEg-C-yOjWcuPOqjw78Eq0XasGJR8Fw41nJ63hXoflLjKtWAJbS9MWfL1-vuZfK__FpE3zCIw0NUcYxUVdIbJChv9kPVHEpN-85YgH5bxV_fNycfs371BEjWaYJbkDi4/s1600-h/2010-12-05_092756%5B2%5D.png"><img alt="2010-12-05_092756" border="0" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHX1tLfe_ongrRRpS92yydMe9adB61FWs4yrbTQmC_vo8_OwaMspt1j2-y68kv41ve4qaVssalR8yrzcaI9-cgiM6c4wk75TnG6uTz2o5D4dw21Lj5le9qlJ5Y2Fo9T4V-AvRy6QX6VRN8/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_092756" width="217" /></a><br />
</li>
<li>Create a new method called <b>DisplayCustomer</b> containing the following code: <pre class="c-sharp" name="code">public void DisplayCustomer(int customerKey)
{
// Call the Web service.
using (var service = new
Assignment3Service.WebServiceSoapClient())
{
var result = service.GetCustomerByKey(customerKey);
if (result != null)
{
var items = result.Tables["Customer"]
.Rows[0].ItemArray;
var limit = items.GetLength(0);
for (int i = 0; i < limit; i++)
{
var item = items[i];
this.Cells[1, i + 1] = item;
}
}
}
}</pre><br />
</li>
<li>Right-click on the Excel Workbook project and choose <strong>Add New Item</strong>:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TRAjElqoWeI/AAAAAAAAAVA/rjl-Gl07xWA/s1600-h/2010-12-05_093805%5B2%5D.png"><img alt="2010-12-05_093805" border="0" height="85" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TRAjExrWV3I/AAAAAAAAAVE/YxetlUvAOVw/2010-12-05_093805_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_093805" width="244" /></a> <br />
</li>
<li>Select <b><i>Office</i></b> under the <b><i>Visual C# Installed Templates</i></b> then choose <b><i>Ribbon (Visual Designer)</i></b> and click <b><i>Add</i></b>:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjFNQ4nkI/AAAAAAAAAVI/vpKUQuWToQM/s1600-h/2010-12-05_093910%5B2%5D.png"><img alt="2010-12-05_093910" border="0" height="170" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TRAjFnAnnSI/AAAAAAAAAVM/rSqDoaJIfJk/2010-12-05_093910_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_093910" width="244" /></a> <br />
</li>
<li>From the Toolbox drag an <b><i>EditBox</i></b> control then a <b><i>Button</i></b> control onto the designer surface:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiatxEl0eSu2laJ5AEj40O8r1VjJAdDkuRlUuEmBO_Fd0l1FjIZf6IH2-g7XtW_KvqKaBwjBLLhcj5M963HpXQLJzw_sqEh_bsm9FyVNUkV1FLMhCr_9s9CAAhmQPD5l5In6K_UvZzOnvcr/s1600-h/2010-12-05_094125%5B2%5D.png"><img alt="2010-12-05_094125" border="0" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKLyjOC6QYch8p-VlJGR0G4lnhyphenhyphenf_H637ocwx7xvRgzHnXSLEBwiTEcetL2qS7-pYFusIqY2c55_7pCqlephIG0qca-ubCxv7UvhHAzwNOkExzfJ-PtHpA01lEOOqU4y3tTlUWjxPX8a68/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094125" width="244" /></a><br />
Resulting in the following:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TRAjGcW0zZI/AAAAAAAAAVY/oSjGXTd1zRc/s1600-h/2010-12-05_094212%5B2%5D.png"><img alt="2010-12-05_094212" border="0" height="226" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjGkBWy0I/AAAAAAAAAVc/lEQmNfMPMr0/2010-12-05_094212_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094212" width="239" /></a> <br />
</li>
<li>Clean up the Labels to make the Ribbon more meaningful and useful:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TRAjG00ydRI/AAAAAAAAAVg/MWNsx55axEc/s1600-h/2010-12-05_094313%5B2%5D.png"><img alt="2010-12-05_094313" border="0" height="168" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TRAjG_1Yh8I/AAAAAAAAAVk/CV_ZePs-IIc/2010-12-05_094313_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094313" width="238" /></a><br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TRAjHGACVxI/AAAAAAAAAVo/VxMAeX6VemQ/s1600-h/2010-12-05_094332%5B2%5D.png"><img alt="2010-12-05_094332" border="0" height="144" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TRAjHTx9L9I/AAAAAAAAAVs/5TSNVVh_29w/2010-12-05_094332_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094332" width="244" /></a> <br />
</li>
<li>The completed Ribbon should look similar to this:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjHvxm2DI/AAAAAAAAAVw/xB2DY4w8KUc/s1600-h/2010-12-05_094451%5B2%5D.png"><img alt="2010-12-05_094451" border="0" height="169" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TRAjH_XvHYI/AAAAAAAAAV0/pZHAVWJdht8/2010-12-05_094451_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094451" width="229" /></a> <br />
</li>
<li>Double-click on the Search button (text) on the Ribbon to jump to the event-handler section. Put the following code to call the add-in method DisplayCustomer previously created:<br />
<pre class="c-sharp" name="code">private void btnSearch_Click(object sender, RibbonControlEventArgs e)
{
Globals.Sheet1.DisplayCustomer(int.Parse(CustomerKeyBox.Text));
}</pre><br />
</li>
<li>Notice as you start typing that Intellisense will provide filtered statement completion:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRUrE60bqPMiHNbB47lf4hHp8WDRKUOGQzpq-iwhg9hgFgaS8zle53yHCfOiVeX7khyXkYc7S20eZIwbR3mqBOftLQ7gI728aio_tUCyOEJ0Q7VLrQBOPCFVS82M8fZlWEa-krN9T_2Hv/s1600-h/2010-12-05_094538%5B2%5D.png"><img alt="2010-12-05_094538" border="0" height="59" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjIFT0T5I/AAAAAAAAAV8/8tKn6ypPr1c/2010-12-05_094538_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094538" width="244" /></a><br />
</li>
<li>Here is the completed method:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjIQDPN-I/AAAAAAAAAWA/XXBU-aqiD6g/s1600-h/2010-12-05_094721%5B2%5D.png"><img alt="2010-12-05_094721" border="0" height="37" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjIkSSnBI/AAAAAAAAAWE/JxIdXB70uRw/2010-12-05_094721_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094721" width="244" /></a><br />
Pay attention to the name of the control (shown as “<strong>CustomerKeyBox</strong>” above) – this name must match the name you gave to the <strong>EditBox</strong> control immediately preceding this step.<br />
</li>
<li>Now press <strong>F5</strong> to debug the solution. Doing so will launch Excel 2007 (or Excel 2010) and you’ll notice the Add-Ins tab of the Ribbon UI displays your custom fields:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC8wGNYdBGvOMQdHNpi3DKiacK_zxTFw1tRJQJiYehGtJr-mU0iREHTIK70_yJjT0qi0LyckqoCrWdH5EsEA4nmqhqqEW4ZbP5Qw-24EV7fUbN9KJFDZmE_FPSzF8joaNtxva-PX8GndWp/s1600-h/2010-12-05_094814%5B2%5D.png"><img alt="2010-12-05_094814" border="0" height="71" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMlC65WnGPmJJJtEFaS1XVCKVJ5kFvTJVvAInYxNE26rtYpPOGKdqNmjKEHQYWHBweQokM1D7WQG25xvwnxiJP_MBwRCwG4OUf4hJj6MKGEA-cNUbkpCKKr4c8UxpkW1124hFNJFsFMrZU/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_094814" width="244" /></a><br />
</li>
<li>Simply type in a customer number then click Search, the results should look something like this:<br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TRAjJpLRW8I/AAAAAAAAAWQ/KWjqz6SAHCs/s1600-h/2010-12-05_110725%5B2%5D.png"><img alt="2010-12-05_110725" border="0" height="97" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TRAjJ08RQPI/AAAAAAAAAWU/BZw8119UK5Q/2010-12-05_110725_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_110725" width="244" /></a></li>
</ol>At this point we have used a custom add-in running on a client desktop to invoke a web service published and deployed in IIS which in turn connects to a SQL database to execute a query using the data supplied by the client (customer key value) and the results are returned and displayed in Excel.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-42184322991819006312010-12-22T06:00:00.002-05:002010-12-22T10:29:20.467-05:00How To Build an ASP.NET 4.0 Web Service and Consume It With Excel 2007-Part 1This short series builds upon the previous <i>How to Build a 2-Tier ASP.NET 4.0 Web Site</i> (Parts <a href="http://pragmatic-software.blogspot.com/2010/12/how-to-build-2-tier-aspnet-web-sitepart.html"><b>1</b></a>, <a href="http://pragmatic-software.blogspot.com/2010/12/how-to-build-2-tier-aspnet-40-web.html"><b>2</b></a>, <a href="http://pragmatic-software.blogspot.com/2010/12/how-to-build-2-tier-aspnet-40-web_20.html"><b>3</b></a>). If you’re jumping in here you’ll need to adjust accordingly.<br />
<ol><li>Right-click on the web project in Solution Explorer, choose <b><i>Add New Item</i></b>:<br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ-2pT8fCOI/AAAAAAAAAS4/rcWplMTkhNo/s1600-h/2010-12-04_221654%5B2%5D.png"><img alt="2010-12-04_221654" border="0" height="75" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqc7yasQIZPRVb6YzR1e51TRjJqti9CNPmHMatnaaSNjuOmLZQueiTYoiXFLZCzYxph7hl0YfSYLnkA2BahyphenhypheniA5nne1sJyx1guDpMegWNsIOqZ-EjEdErEo7SRUnVMMCcAxOWfHq9naJcz/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_221654" width="244" /></a><br />
</li>
<li>Ensure that <b><i>Visual C#</i></b> is chosen under <b><i>Installed Templates</i></b> on the left, select <b><i>Web Service</i></b>:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQ-2qLfSO5I/AAAAAAAAATA/QE0Yo1JgQiU/s1600-h/2010-12-04_221753%5B2%5D.png"><img alt="2010-12-04_221753" border="0" height="170" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ-2qucVO0I/AAAAAAAAATE/kxJ_FVD84X4/2010-12-04_221753_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_221753" width="244" /></a><br />
</li>
<li>Replace the default boilerplate code show here:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQ-2rJ4S6sI/AAAAAAAAATI/-GgY4LS5EUw/s1600-h/2010-12-04_221902%5B2%5D.png"><img alt="2010-12-04_221902" border="0" height="206" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ-2rTFYdiI/AAAAAAAAATM/sXkfS7528cc/2010-12-04_221902_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_221902" width="244" /></a><br />
With the following code (begin replacement on <b><i>line 10</i></b> above): <pre class="c-sharp" name="code">[WebService(Namespace = "http://pragmatic/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService :
System.Web.Services.WebService {
[WebMethod]
public DataSet GetCustomerByKey(int CustomerKey)
{
DataSet resultSet = new DataSet();
SqlConnection conn = new SqlConnection(
ConfigurationManager.ConnectionStrings["AdventureWorksDW2008R2ConnectionString"]
.ConnectionString);
using (SqlCommand cmd = new SqlCommand(
@"SELECT [LastName], [FirstName], [MiddleName], [BirthDate], [EmailAddress], [Phone]
FROM [DimCustomer]
WHERE ([CustomerKey] = @CustomerKey)"))
{
cmd.Parameters.AddWithValue(
"@CustomerKey", CustomerKey);
conn.Open();
cmd.Connection = conn;
SqlDataAdapter dataAdapter =
new SqlDataAdapter(cmd);
dataAdapter.Fill(resultSet, "Customer");
}
return resultSet;
}</pre></li>
<li>Here is the resultant web service code-behind file:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw8DVgO4A0567W-j4XYaOaN2mRFV3078-BH41XPG7A4BmCeJYP_LPuNMJmUtaMhbiie3UcfFuZd-AuEeY475KqKxkeVU72RmVcOS7PpDsagDKdckgA6eknzBKooqlzn2rS4jyk11BwHBY2/s1600-h/2010-12-04_223404%5B2%5D.png"><img alt="2010-12-04_223404" border="0" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEig23mKhZWlWx9pUW5PJS37XE9dXKaDzMQVJ395UaYJIMugdtpOUkQmYemi9nd59nSzE-vaFC8rElcTZkLSsWGEkKTLgq6l4xftC1aMwyZ7ro-NRmbpzSOFEyi0sxQVoXj5i0ycO_HE73zr/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_223404" width="244" /></a><br />
</li>
<li>Explanation of above lines:<br />
<u>10</u>: Replace default namespace with meaningful one.<br />
<u>12</u>: Define a web method called <b><i>GetCustomerByKey</i></b> which accepts an integer assigned to the variable “<b><i>CustomerKey</i></b>” and returns an ADO.NET DataSet object.<br />
<u>17</u>: Declare an ADO.NET DataSet that will be populated with the results of the Sql query.<br />
<u>19-20</u>: Declare an ADO.NET <b>SqlConnection</b> used to connect to the Sql database <b><i>*AND*</i></b> initialize the connection string using the same value previously stored in the configuration file from Part 3. Note that your connection string value (shown here as “<b>AdventureWorksDW2008R2ConnectionString</b>” may be different. Open web.config file to obtain the actual value to use from the “name=” attribute:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyGfHoiPFhPH4qSYeJtMyo0Xsz82WvK1Dxk5s7rFOtX0fPePPXsqt4mLXq8zTEm31-o4SDuUkDIjbRttNk-sRXmpefE_Wc8RZ6XEURm5E5oJz_hMyjQshunrNZdDKQsOmdDzgBFVeovmxZ/s1600-h/2010-12-05_114702%5B2%5D.png"><img alt="2010-12-05_114702" border="0" height="77" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR7EvK7CxqYsRgusnJiwoAPZbmbxLCXK46jZgl9kMY1v13g0pJ-3xMw1nO99XPQxYmkhCm5b7TUMD086uNIb8tD1K-7gO2-Kf_HlFhSH0hr625CIMYxAn0-YqI_zmo6ccaiQACrmjq8MLa/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-05_114702" width="244" /></a><br />
<u>22-24</u>: Construct a <b>SqlCommand</b> using the same SELECT statement previously used in Part 3. Note the “<b>@CustomerKey</b>” parameter token.<br />
<u>26</u>: Add an entry for the <b>@CustomerKey</b> parameter token and set its value to be the variable that is passed into the web method.<br />
<u>27</u>: Open the connection to the database.<br />
<u>28</u>: Associate the open connection to the <b>SqlCommand</b> object so the command will use it.<br />
<u>29</u>: Declare an ADO.NET <b>DataAdapter</b> and associate it to the <b>SqlCommand</b> object. This “magic” object will take care of a TON of work executing the <b>Sql</b> statement, taking the query results returned from the database and filling the collection of .NET <b>DataSet</b> objects (tables, rows, columns, values) with the result of the query.<br />
<u>30</u>: Simple little statement calling the Fill method of the <b>DataAdapter</b>, giving it the command to use and the dataset to be filled. This is the truly “magic” part of high-level object oriented programming.<br />
<u>32</u>: Return the populated dataset to the caller of this method.<br />
</li>
<li>To test the web service, simply press “F5” or click the green arrowhead on the toolbar next to “Debug”. When the web browser comes up, type the name of the web service file in the address bar and hit enter:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ-2tgrVRyI/AAAAAAAAATg/-I2OkXZEy-I/s1600-h/2010-12-04_224423%5B2%5D.png"><img alt="2010-12-04_224423" border="0" height="31" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ-2uBevfKI/AAAAAAAAATk/2INNn3Cl2Nw/2010-12-04_224423_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_224423" width="244" /></a><br />
Remember that your port number may be different than the <b>:</b>1483 shown above – that’s okay.<br />
</li>
<li>You should see the sample web service test page shown here:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ-2urvBOII/AAAAAAAAATo/dTtrh6hF8YA/s1600-h/2010-12-04_224441%5B2%5D.png"><img alt="2010-12-04_224441" border="0" height="66" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ-2u0fl_pI/AAAAAAAAATs/3sYCKsg37WE/2010-12-04_224441_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_224441" width="244" /></a><br />
</li>
<li>Click the “<b>GetCustomerByKey</b>” hyperlink and you’ll see the test page for the web method:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtOFPf9uUSEvRi8qmc4RYYpvZTK7KEqy-PxJ4Wp8P9BlKl6z4pRvicZACD2FVRuhMbMnnZjyTvs9fhvtuivhuWxSO4RoliPSGWZu8o9wuHqGR4BP6F8cgpdckYVIti93NqHxZqyyL1VjO9/s1600-h/2010-12-04_224514%5B2%5D.png"><img alt="2010-12-04_224514" border="0" height="204" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQ-2vx5zcZI/AAAAAAAAAT0/0jnyV3FKcX0/2010-12-04_224514_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_224514" width="244" /></a><br />
</li>
<li>Input a value, such as 11000 and click invoke to see the results of the web method:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ-2wFj79PI/AAAAAAAAAT4/LQNd5SSOT-8/s1600-h/2010-12-04_225618%5B2%5D.png"><img alt="2010-12-04_225618" border="0" height="210" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ-2wtF7rqI/AAAAAAAAAT8/pBaqDcGofxg/2010-12-04_225618_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_225618" width="244" /></a><br />
</li>
<li>You can re-publish the website as shown in the first few steps of Part 3 – no need to go through all the one-time configuration steps however. Verify the web service is published by opening a browser and typing in the correct address:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQ-2wxNzk8I/AAAAAAAAAUA/4ZtUF8wG-NU/s1600-h/2010-12-04_232205%5B2%5D.png"><img alt="2010-12-04_232205" border="0" height="28" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ-2xec4_-I/AAAAAAAAAUE/tiPtp4SXXik/2010-12-04_232205_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-04_232205" width="244" /></a></li>
</ol>Next time we’ll use Excel to quickly test consuming the published web service with very little effort.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-75127103489005353282010-12-20T06:00:00.001-05:002010-12-22T10:34:52.794-05:00How To Build a 2-Tier ASP.NET 4.0 Web Site–Part 3Now that <a href="http://pragmatic-software.blogspot.com/2010/12/install-iis-75-on-windows-7.html">IIS 7.5 is installed on Windows 7</a> let’s move on to deploying the website to IIS and testing it there.<br />
<ol><li>From the <b><i>Build</i></b> menu choose <strong><em>Publish Web Site</em></strong>:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10Un0VlJI/AAAAAAAAAQ4/Eh_Jl7bAgD0/s1600-h/2010-12-01_232940%5B2%5D.png"><img alt="2010-12-01_232940" border="0" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRk_6YKg2i30ncZ9F1_Oal5FPbXU6geX5fSNWsXF3sXTVrVTwNilINLHecPubBaX-3BynYjzI0XHxw7mcUmEyIY2abH9g7kz3CFgJZuITvBxDJbduNf9Rxked-jAjhLnUinP7RvU8dPGU9/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232940" width="143" /></a><br />
</li>
<li>You can either accept the default location or change it to something else:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQ10VrNuEnI/AAAAAAAAARA/1EWBMYHbf9I/s1600-h/2010-12-01_232958%5B2%5D.png"><img alt="2010-12-01_232958" border="0" height="170" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10WN9iInI/AAAAAAAAARE/GnW1Y14uEcE/2010-12-01_232958_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232958" width="244" /></a><br />
Make note of the location chosen as you will need it shortly.<br />
</li>
<li>Now let’s configure the website in IIS 7. Launch IIS manager from <b><i>Control Panel</i></b> | <b><i>Administrative Tools</i></b> | <b><i>Internet Information Services (IIS) Manager</i></b>:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0ZX6yx8Ii_5i-clzVn4xrROYIuMwRnA-pgOllJmFwxKqiFFkW_W98S-RGFY610vmQCWSdZGKv9eSmhueAvLk6K8AL4jnaceRfMGU2uh2dcHcLvYY12OStomWSHjlET_4s0cUWdmMSnKCq/s1600-h/2010-12-01_225342%5B2%5D.png"><img alt="2010-12-01_225342" border="0" height="67" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjJC0_Cb_R0bQ0qY0SAlay9RyyqE1rOZIECKzd9Dbc6o6yD182OpWGcnGKxtr-5RfBubbb7PJgyV6taEMjTD2nzzVEGU0S6lU4Osr_nxOE72Q8frIjga8iTXjyS1Ztff5CZvAgN-4a_Rh0/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_225342" width="244" /></a><br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10Xlm87XI/AAAAAAAAARQ/0sQjVEX6Fmo/s1600-h/2010-12-01_225416%5B2%5D.png"><img alt="2010-12-01_225416" border="0" height="47" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ10YNaxf2I/AAAAAAAAARU/4OqnyXECA3g/2010-12-01_225416_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_225416" width="244" /></a><br />
Hint: IIS Manager is the configuration tool for IIS and you’ll be jumping into it often. You can use the Run dialog for faster access via the <strong>Windows + R</strong> then typing “<strong>inetmgr</strong>”:<br />
<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQWRsVQTn8I/AAAAAAAAAPo/uA0yJOz0JwA/s1600-h/2010-12-01_225504%5B2%5D.png"><img alt="2010-12-01_225504" border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1VCxk2aQtTziwcuBMNijma16POcLQWBYHwcUNjykdipefDSywtkktZEXiYRTY3E7a794ppU8igMuPoEqvyCzQLt_1vrCEE7c-QTDfmxG3NKBmVAh06uZx9eB5Rgx-lFxYNm_0CdR-TfRK/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_225504" width="212" /></a></li>
<li> Expand the tree control on the left, right-click on <b><i>Default Web Site</i></b> then right click and choose <b><i>Add Application</i></b>:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ10YfX0bDI/AAAAAAAAARY/LY7yrm39MzU/s1600-h/2010-12-01_233031%5B2%5D.png"><img alt="2010-12-01_233031" border="0" height="130" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10Yxl4nZI/AAAAAAAAARc/uy2APkW2Nh0/2010-12-01_233031_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233031" width="244" /></a></li>
<li> Type in an <b><i>Alias</i></b> name that will be used as the website name when browsing, Select the <b><i>ASP.NET v4.0 Application pool</i></b> and choose the same <b><i>Physical path</i></b> where you just published the website to previously. You should click the <b><i>Test Settings</i></b> button to verify that Authentication and Authorization are configured correctly:<br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10Z01HGHI/AAAAAAAAARg/YXtLe3Dx7Yk/s1600-h/2010-12-01_233205%5B2%5D.png"><img alt="2010-12-01_233205" border="0" height="169" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10aGkunDI/AAAAAAAAARk/7i7QM2goUtQ/2010-12-01_233205_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233205" width="244" /></a><br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10aQ-1cDI/AAAAAAAAARo/7y2N2oSshWs/s1600-h/2010-12-01_233703%5B2%5D.png"><img alt="2010-12-01_233703" border="0" height="165" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10a4VA-fI/AAAAAAAAARs/uOlYiktzS6g/2010-12-01_233703_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233703" width="244" /></a></li>
<li> If you received the above Authorization error it means that IIS does not have permission to access the folder where you published the website to. If this occurs, click <strong><em>Close</em></strong> then <strong><em>OK</em></strong> to complete the creation of the application. Back in the tree view control right-click on <b><i>Edit Permissions</i></b> to grant the IIS web server permission to the publish folder:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10bIbn_JI/AAAAAAAAARw/XuPMkPtJcc0/s1600-h/2010-12-01_233315%5B2%5D.png"><img alt="2010-12-01_233315" border="0" height="137" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10bSNxuoI/AAAAAAAAAR0/3HzwA7kdqpA/2010-12-01_233315_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233315" width="244" /></a></li>
<li> On the Security tab choose <b><i>Edit</i></b>, then <b><i>Add</i></b>, then <b><i>Advanced</i></b>, and finally <b><i>Find Now</i></b>:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10bke1s5I/AAAAAAAAAR4/LOKJy6e5zS4/s1600-h/2010-12-01_233348%5B2%5D.png"><img alt="2010-12-01_233348" border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlQvDphYInUXAOHTi7LFbX2VGT3c-pwKwOkHhGUaQvoNs5WplHKuoH7p874NBCmJPG64LaENSQQBUECxmXylGbqEubn1RppPX18RxGU0UgrgThQPKXX1x1aDq1i9UtZ0A5ZH-D7apKVtSZ/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233348" width="244" /></a><a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10cZyud0I/AAAAAAAAASA/aN1_bnBpPCc/s1600-h/2010-12-01_233404%5B2%5D.png"><img alt="2010-12-01_233404" border="0" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg22_HLTenxT8nszmTJsNepnDdZ-8dtKJCrAtrz9oAd4vjf8W_fPI0-LdZRh-ZJm3tsKyggTKUbsH-xg0b01RpkSjyHJHiWRcCmb94KgF2X1Cl8bb3ssaxLp7asBKpLRGTGiVfN7C8X0DTT/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233404" width="244" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjexo0RCEmMcdA_TlcXbbZPW_aqE-Yiao5lgkWeIgbziZqhJCBDcZP_61aXeXxnpuvTh1jF3_PVuxn3aELZBCxgy-WhBxpjoX16MnMxnkc2ScCpKXLJ_jlrS9PljFjQmOk1KT4id-G-hfHj/s1600-h/2010-12-01_233423%5B2%5D.png"><img alt="2010-12-01_233423" border="0" height="225" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10dVt-NKI/AAAAAAAAASM/qQU88xyGoGs/2010-12-01_233423_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233423" width="244" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5dtfyG_8fkKqmUKeKJt7CyHU5XKosbCpeqnNILFH2cIIwlCrJ6U8Z3vHdIhFukg-JBiRgNyP_Ka9kEgNM54yinxJWFMlAXwUMPXCCmDqU-mFh-A6qCl3G4o7KP06N5raaXKMmrTEG_uYp/s1600-h/2010-12-01_233445%5B2%5D.png"><img alt="2010-12-01_233445" border="0" height="202" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10eXwpnEI/AAAAAAAAASU/4CSjSwaglT4/2010-12-01_233445_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233445" width="244" /></a></li>
<li> From the list of users and groups use <b><i>Control + click</i></b> to select the follow three: <br />
<ul><li>IIS_IUSRS<br />
</li>
<li>IUSR<br />
</li>
<li>NETWORK SERVICE </li>
</ul><a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQ10e5-fE6I/AAAAAAAAASY/fOSyuE-kPmc/s1600-h/2010-12-01_233512%5B2%5D.png"><img alt="2010-12-01_233512" border="0" height="244" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQ10fYcj1wI/AAAAAAAAASc/cb1ZlpEcgYs/2010-12-01_233512_thumb.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233512" width="221" /></a> Now you can click <strong><em>OK</em></strong> through until the dialogs are dismissed, right-click on the Website in the tree control again and choose <b><i>Edit Application</i></b> where you can Test Settings again.</li>
<li> When testing from within Visual Studio we are running under the permissions of ourselves – the account we signed into Windows with. When browsing against IIS, it is IIS that is connecting to the database. Since the IIS web server will be acting as a proxy for the user when accessing the database, you must grant the IIS user permission to the database. Using SQL Server Management Studio, execute the following T-SQL statements:<br />
<pre class="sql" name="code">CREATE LOGIN [IIS APPPOOL\ASP.NET v4.0]
FROM WINDOWS
WITH DEFAULT_DATABASE=[master],
DEFAULT_LANGUAGE=[us_english]
GO
CREATE USER [AdventureWorksUser]
FOR LOGIN [IIS APPPOOL\ASP.NET v4.0]
GO
EXEC sp_addrolemember 'db_datareader', 'AdventureWorksUser'
GO
</pre><br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ10f8-42dI/AAAAAAAAASg/b_2G7jnlHw0/s1600-h/2010-12-02_000021%5B2%5D.png"><img alt="2010-12-02_000021" border="0" height="167" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQ10gBooNTI/AAAAAAAAASk/V-8OmSTj9TY/2010-12-02_000021_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-02_000021" width="244" /></a></li>
<li> Finally right-click on the website again, choose <strong><em>Browse</em></strong>:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhZSQfu-aUJ38mX7MC4sRgJuPkGuu720_mhdeK93cNC13BoUFiRMwQh_H4hWjiAqcaL3EjYOhr1nuyeMdAC8-HoXKNUnKxqYGBFnyRzhr381RZyZWN4oAKy4edK107KRSj5APn4Nb4LpvE/s1600-h/2010-12-01_233228%5B2%5D.png"><img alt="2010-12-01_233228" border="0" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm71Qyjr5ALGJ0T4oytXAJG8J1RfT-fuu17_s3LmG5739MManXOiyuXnHCvGiDlauX1Q6zJ3_rRZxSCXAoP7HYf9IwO0rCZd7sCbZ_wbISOEihTu3d2pSpnVsTJtiRZlGg9pWsZTjVAK6p/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_233228" width="244" /></a></li>
<li> Sit back and enjoy the fruits of your hard labor:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQ10h9eaFNI/AAAAAAAAASw/NdOu6VbZqSg/s1600-h/2010-12-02_000036%5B2%5D.png"><img alt="2010-12-02_000036" border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbnCTNowl5vlxc6fW4hkzSGpbY-G9_Yu5tunsl8sKwXG0plfAN1pWdjHYw9M_1fSkA-pATfEj0MfubbkA30YNr_s6xSNxw5BH0NWRMNAwVKmjxnCqOpisJSJ3NZNt0n03bL-8sM4oBEQzd/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-02_000036" width="244" /></a></li>
</ol>While testing the site in IIS is not absolutely required, it is helpful to go through the publishing process to help shake out potential problems such as the fact that IIS runs under a service account and not the you (the logged in user) the way Visual Studio’s build in web server does.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-88320390448908857532010-12-18T13:30:00.001-05:002010-12-18T14:09:41.834-05:00TD Bank website team is sloppy<p>Hmmm…Saturday before Christmas here in the U.S. of A., major banking site, error page like this:</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6nNnjnxTkYvK4wjHH9OpKg3FFhMdZb1XxI8kCOFX2A-hBlSpwr84TzNIkdc_CtCL_-_SjimXaGRp4wHtvnZ5b2nUtKuY6TQ5UH41I_BhGz1VPWAxrzSz-vgiNEc4ybB5fKDcqcBjX2V64/s1600-h/TDBank_error%5B5%5D.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="TDBank_error" border="0" alt="TDBank_error" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQ0G8jGJnJI/AAAAAAAAAQ0/6g8v18DYuZI/TDBank_error_thumb%5B1%5D.png?imgmax=800" width="244" height="210"></a></p> <p>I’ve been developing in ASP.NET since 2002 so I think I can safely say that somebody screwed up and they’ve got some sloppy practices in place!</p> <p>Looks like ‘Banknorthct’ is a valid #bankid# token in case you’re trying to discover information about their site. Also, they like to use D:\websites to store their site files in so hackers shouldn’t have to go hunting for that configuration detail. Finally, they’re running .NET 2.0 which means it’s a lot easier for folks to attack because they can immediately try all known exploits.</p> <p>Do I seem too harsh? Well, two simple steps would’ve prevented this:</p> <ol> <li>Turn ‘<a href="http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx" target="_blank">RemoteOnly</a>’ back on in your web.config – someone explicitly changed it from the default value.</li> <li>Code a custom error page possibly with a redirect so the customer doesn’t see your dirty underwear!!</li></ol> <p>Tell me again how much banks got for a bailout in ‘09 and ‘08 and how much profit are they raking in now?</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-72548761739393024652010-12-15T06:00:00.000-05:002010-12-15T06:00:04.324-05:00Install IIS 7.5 on Windows 7<p>Here are the quick steps for installing IIS 7.5 on Windows 7 Professional/Enterprise/Ultimate. While Microsoft’s TechNet does have <a href="http://technet.microsoft.com/en-us/library/cc725762.aspx" target="_blank">an entry</a> it’s not the most informative or person-friendly (person being different than a techie geek). This post is a companion to the How To series on building a 2-tier ASP.NET 4.0 web site (<a href="http://pragmatic-software.blogspot.com/2010/12/how-to-build-2-tier-aspnet-web-sitepart.html">part 1</a>, part 2, part 3).</p> <ol> <li>Navigate to <strong>Control Panel</strong> | <strong>Programs</strong> | <strong>Turn Windows features on or off</strong>:<br><a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQWRjIBepqI/AAAAAAAAAOQ/5_MfsmolIik/s1600-h/2010-12-01_223350%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_223350" border="0" alt="2010-12-01_223350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEis6ygirA2vsisr1SoWCaDT5PkEArd3_yfE7uPrP79DTK0VNpE3Dy2tbkwvzB37zgi6qTgqrH-lCLMSDvH0Apze4SeFeKUoEVDmZ5q-9GKFt0pH3lnKEY78wTFggdA7Z2RcYE58JD4HcZEx/?imgmax=800" width="244" height="31"></a><br><a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQWRkpzWy8I/AAAAAAAAAOY/91gUTD_YwbI/s1600-h/2010-12-01_223854%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_223854" border="0" alt="2010-12-01_223854" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7WlmpmBgdkPvbJb8xbl0M3PSfj-AD8s2ybnfCavGYp7RHvy2twJhhT6Vga38Z1mkm4hXRWlpa5X-VUknmLjp0sZV6qDGnv1wbZq6IQumQffOYvB6ACJhStm52AtxjEUtdsvUiMlLpfrHe/?imgmax=800" width="244" height="91"></a><br><a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQWRlIVmnJI/AAAAAAAAAOg/OSakBLLz9lU/s1600-h/2010-12-01_223914%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_223914" border="0" alt="2010-12-01_223914" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRlr7zJxI/AAAAAAAAAOk/Nr4iuGp9vCs/2010-12-01_223914_thumb.png?imgmax=800" width="244" height="47"></a> <li>Check the box next to <strong>Internet Information Services</strong> and then expand the sub-tree by clicking the (+) plus sign next to it:<br><a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQWRlxQ4q4I/AAAAAAAAAOo/mOWsB-DXT2U/s1600-h/2010-12-01_223942%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_223942" border="0" alt="2010-12-01_223942" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiftpmM_o3MOmbYHwMPW0sKK1IYPNvVklWQxTMFeKIF7_FvQWQeXM0e7z34TLm1T6C6CL8cOE2TqK47YJG8lanuCxe1h336Xg-TwX-DfvTtsClUwbBgfi9v5eEmj89NmMBPb1Hil8OzOpp3/?imgmax=800" width="244" height="135"></a> <li>Continue expanding the sub-tree until you open <strong>Application Development Features</strong> then check the box for <strong>ASP.NET</strong>:<br><a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQWRmgVYsSI/AAAAAAAAAOw/720BL-veMj4/s1600-h/2010-12-01_224027%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_224027" border="0" alt="2010-12-01_224027" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQWRm4QgUfI/AAAAAAAAAO0/8_o-mqU3ws8/2010-12-01_224027_thumb.png?imgmax=800" width="244" height="115"></a> <li>Further down, expand <strong>Security</strong> then enable <strong>Basic Authentication</strong> and <strong>Windows Authentication</strong>:<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Uv_A5Rn23aw7LGYBmnrHsYyTM85PuLV99UiODX48xHQ6CHPzh6-TwR1USfw-Lb7bXJBLRrTHpDC9e1aBwhFhizmbrJUtozlBps3Dv94qJDnGS8s1eigMCUSUwjjbLtB1Ah6Ge28f7y5Z/s1600-h/2010-12-01_224124%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_224124" border="0" alt="2010-12-01_224124" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQWRoQrZ6yI/AAAAAAAAAO8/7HMUEEZkepw/2010-12-01_224124_thumb.png?imgmax=800" width="244" height="129"></a><br><a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRolJv55I/AAAAAAAAAPA/ypPry84wT3Q/s1600-h/2010-12-01_224136%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_224136" border="0" alt="2010-12-01_224136" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaGKgJkGo_Bzx8UWz4NQhuhUedEvDkskG-RPaiZrPHf5DXyp0bbWLRhHY8XXsFccXCNpmxCQ0LJkFFxPCqh-3darwU535496Su5nDciWlOs7JAkX1jk8VHg7-95hNTRczsDFEb1Gj0M2h6/?imgmax=800" width="244" height="128"></a><br>Clicking OK to close the dialog out will cause the computer to install and pre-configure IIS, taking several minutes to complete. <li>After IIS is installed you’ll find a new set of folders has been created:<br><a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQWRpu9W0VI/AAAAAAAAAPI/Lq51UzO-IDI/s1600-h/2010-12-01_225259%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225259" border="0" alt="2010-12-01_225259" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRqMI1OEI/AAAAAAAAAPM/0XtQlwfHE8Q/2010-12-01_225259_thumb.png?imgmax=800" width="244" height="183"></a><br><strong>C:\inetpub\wwwroot</strong> is the default “root” folder for IIS (a.k.a. world wide web server) so this path is the default location to place websites. The key fact here is that if you publish into this folder you won’t have to worry about folder (NTFS) permissions. Publishing to the default personal user location that Visual Studio selects – within your “My Documents” folder means you need to take an extra step of granting IIS permission to access those folders in your documents area. This screenshot from IIS Manager shows the default web site along with the path matching the path shown above:<br><a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQWRqUhuAMI/AAAAAAAAAPQ/5WVwhKmOqqc/s1600-h/2010-12-01_230027%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_230027" border="0" alt="2010-12-01_230027" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE8_BrRLpCIkvkJ3dC8sM-CyyIcvwV8QH2Vkp8WnNuq2HVMpYFR_xOWytD7FlJduy1uFXMnAs62WdD8Pu6GkDoLKgEDdtW8dqb_R67aHXPDJlMIDDLC9t3i_6DTLlchap7NoP3cj44nm1p/?imgmax=800" width="244" height="47"></a> <li>Next we’ll configure Application Pools that will host and execute the ASP.NET applications. Launch <strong>IIS Manager</strong> from <strong>Control Panel</strong> | <strong>Administrative Tools</strong> | <strong>Internet Information Services (IIS) Manager</strong>:<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjLiED6GZq6fdQBvrBosaILmMDr6mQlAjTpFpJsufFANj_pNh6TeFuMzrmqlujWxSXMTi6psp5to_wxrAZb-aqps0fQTK9-ngtGzMWGmkCOOaN3Xs43pNsQPuPeV4qTHa7DzJGarvwT0uH/s1600-h/2010-12-01_225342%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225342" border="0" alt="2010-12-01_225342" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZbxv56-cdNLsz-tNl44GD5aGs8W5oSyLlmbIAE55_hj2ZsTCTt0uaWjEsJpDdYfrvAzmIcVGCW5g4vaBuavN2yPGEyLw828l4cwvxoWGzSwQyBRzy6dl6K7LOBKihyphenhyphenjCkzGP6KOuL1ybS/?imgmax=800" width="244" height="67"></a><br><a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQWRrxKvtSI/AAAAAAAAAPg/m0KGrpwXaos/s1600-h/2010-12-01_225416%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225416" border="0" alt="2010-12-01_225416" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz1qA2v9ymIGFGQfULDVKhe6We7iMq75HvTqvZ_5M5F6vW-3nn7BbXBoyj5wuGPaOh8XQ6Xoqv00D2KV6N5KfyqACuFb1mpXFHCUQgrRoLp21SQfm9wxLdQAt7rJZZumdux3KYH8NgrHg3/?imgmax=800" width="244" height="47"></a><br>Hint: IIS Manager is the configuration tool for IIS and you’ll be jumping into it often. You can use the Run dialog for faster access via the <strong>Windows + R</strong> then typing “<strong>inetmgr</strong>”:<br><a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQWRsVQTn8I/AAAAAAAAAPo/uA0yJOz0JwA/s1600-h/2010-12-01_225504%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225504" border="0" alt="2010-12-01_225504" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1VCxk2aQtTziwcuBMNijma16POcLQWBYHwcUNjykdipefDSywtkktZEXiYRTY3E7a794ppU8igMuPoEqvyCzQLt_1vrCEE7c-QTDfmxG3NKBmVAh06uZx9eB5Rgx-lFxYNm_0CdR-TfRK/?imgmax=800" width="212" height="201"></a> <li>When you select the Application Pools entry in the tree control you should see the following:<br><a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRtN417WI/AAAAAAAAAPw/tXHdsSoIMgk/s1600-h/2010-12-01_225613%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225613" border="0" alt="2010-12-01_225613" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI41bXOl0GW1gU14hYs0QlHo3yHOxsPRrBr4mlGWPb1k0yERWuACwX0mXUOKknTNEfqVQrCdiEkqX2ya8IL3Y9QVoimWhqs7UcrJVtkacbdwHLG9TknxxXj3zRXoB4ije9mRs1sjmezkTR/?imgmax=800" width="244" height="81"></a><br>However, a standard configuration of IIS 7.x on Windows Server 2008 R2 looks like this:<br><a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRtv9TLNI/AAAAAAAAAP4/8VEf5zNqyzM/s1600-h/2010-12-01_225822%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225822" border="0" alt="2010-12-01_225822" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRuKcVswI/AAAAAAAAAP8/MI8SM7MrI98/2010-12-01_225822_thumb.png?imgmax=800" width="244" height="96"></a><br>Notice that the server installation contains two additional application pools configured for ASP.NET v4.0. <li>Let’s configure our personal machine (desktop/laptop) in the same manner to enable more realistic local testing. Right-click on the <strong>Application Pools</strong> entry in the tree control and choose <strong>Add Application Pool</strong>:<br><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYQWwJ1oHA3unUyZI0Hd3Vd1Ws1K6xF8Lw_Q43raWxJyWGxCc3cLtjeFwBGYDD3fXHnqKU4ewcDAvp352nwhYlqI567vB1cKi0XCjjMkC08K_gYxzy5CsTMwmGcmcpbMGi-GzAKSg4TMRV/s1600-h/2010-12-01_225857%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225857" border="0" alt="2010-12-01_225857" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQWRvEdCtkI/AAAAAAAAAQE/dS2Qz9KxFEY/2010-12-01_225857_thumb.png?imgmax=800" width="223" height="244"></a><br>After adding the integrated mode, repeat the steps to add a <strong>classic mode pipeline</strong>:<br><a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQWRvWPG6zI/AAAAAAAAAQI/fGZFw22b0uQ/s1600-h/2010-12-01_225931%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_225931" border="0" alt="2010-12-01_225931" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQWRvzc_cNI/AAAAAAAAAQM/_C6xHftSIFo/2010-12-01_225931_thumb.png?imgmax=800" width="220" height="244"></a> <li>Since IIS was not installed and ASP.NET was already present in Windows 7, we must manually register the “handler” for ASP.NET pages and content so IIS can correctly map web requests. To do so open a command prompt <strong><em>running as Administrator</em></strong> – necessary because this type of registration requires elevated permissions. To open a command prompt as Administrator click the <strong>Start</strong> button, type in “<strong><em>command</em></strong>” and wait a moment until it shows the <strong><em>Command Prompt</em></strong> under the Programs section then <strong><em>right-click</em></strong> and select Run as administrator as shown here:<br><a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQWRwGlwmMI/AAAAAAAAAQU/ZIzxrkf81xo/s1600-h/2010-12-01_234807%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_234807" border="0" alt="2010-12-01_234807" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRwnlH4yI/AAAAAAAAAQY/dbLA_fONDss/2010-12-01_234807_thumb.png?imgmax=800" width="146" height="244"></a> <li>With the command prompt open execute two commands by typing in each of the following and pressing Enter after each command:<br><a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQWRxKPZpbI/AAAAAAAAAQc/4wSE57x4K-0/s1600-h/2010-12-01_235058%5B2%5D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2010-12-01_235058" border="0" alt="2010-12-01_235058" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Klf2qqZyS8xrS1QsfqJzlM7LXffNlJsSXJ5ADNyxBtF3q3LLx7Ow3_0kGLHiyhCsdxJy4MpLW0ElFd-A2Vz2C3EhQIq_7Zf1_kGQ1imumSKVkysZrGIHKV87DsJE9xb6QER1BRmCPHZ_/?imgmax=800" width="244" height="65"></a><br> <blockquote> <p><font face="Courier New">cd %windir%\Microsoft.NET\Framework\v4.0.*<br>aspnet_regiis.exe –i</font></p></blockquote> <p>Note that the last four digits of the build number (30319 shown above) are less important. You may have a different version depending on the service pack level and patches installed in your computer.</p></li></ol> <p>That’s it – you’ve installed IIS, enabled common security features and created application pools designed to host ASP.NET 4.0 websites.</p> Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-2811308028656623966.post-84555944324427939512010-12-13T06:00:00.000-05:002010-12-13T06:00:10.169-05:00How To Build a 2-Tier ASP.NET 4.0 Web Site–Part 2<a href="http://pragmatic-software.blogspot.com/2010/12/how-to-build-2-tier-aspnet-web-sitepart.html">Last time</a> we built a new ASP.NET 4.0 empty web site and set up the Default.aspx web form with a simple prompt for customer number. Now we’ll create a Result.aspx to display the results of a query from the <a href="http://sqlserversamples.codeplex.com/" target="_blank">AdventureWorks</a> sample database. Don’t be alarmed at the length of this part, I simply took lots of screenshots along the way to make it easy to follow.<br />
<ol><li>Add a new page named <strong>Result.aspx</strong> as described previously in <a href="http://pragmatic-software.blogspot.com/2010/12/how-to-build-2-tier-aspnet-web-sitepart.html#addwebform">step 3</a>:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQvMrHDcgp3CwJ7B04OEK-O_mYZDgMxQDxtn2Fi9rHKqdR8Z6YaqqMP8I7oy4SrzaJfuxOfJWGPzhTH54GqYI6UparqCOrd_cf_FT6DxHebYNzXFgJZsP1_sR4NUT87-nqTNmyeSSAVtIm/s1600-h/2010-12-01_231902%5B2%5D.png"><img alt="2010-12-01_231902" border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9S_duiqa68Jcd3M_JlINTXyiAt-o9v6VCkqmN_53l8NL3A1gPgI-ItC-MBaJN6dMZMhv0cnTZoYYhFpQZxdF23vQaOvGBrx66s4I6LhaJCAzJESAgzTds9uNCsNKlymXVUASRMOPRJde_/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_231902" width="244" /></a><br />
</li>
<li>Switch the content area to “split” view using the tabs at the bottom, located the <strong>GridView</strong> control in the toolbox and drag it onto the design surface:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQVRQxEMosI/AAAAAAAAALw/mmUrPzq5ODY/s1600-h/2010-12-01_231937%5B2%5D.png"><img alt="2010-12-01_231937" border="0" height="189" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRRP22F4I/AAAAAAAAAL0/EWagKvuLujw/2010-12-01_231937_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_231937" width="244" /></a><br />
</li>
<li>To configure the data source click on the small arrowhead in the upper right section of the grid view control to expose the configuration pane as shown here:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRRVKP0YI/AAAAAAAAAL4/Muh9hZq4wfE/s1600-h/2010-12-01_232004%5B2%5D.png"><img alt="2010-12-01_232004" border="0" height="74" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRRrB2wbI/AAAAAAAAAL8/nLCpU46yEUI/2010-12-01_232004_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232004" width="244" /></a><br />
</li>
<li>Click the drop-down control next to “Choose Data Source:” above and select “<strong><New data source…></strong>” which will launch the Data Source Configuration Wizard:<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRR9o5tKI/AAAAAAAAAMA/BsXkrgEZUx4/s1600-h/2010-12-01_232044%5B2%5D.png"><img alt="2010-12-01_232044" border="0" height="182" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRSKi80II/AAAAAAAAAME/_GKa8zWAeLg/2010-12-01_232044_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232044" width="244" /></a><br />
As shown above, select the <strong>SQL Database</strong> icon and input a meaningful name (or accept the default).<br />
</li>
<li>Clicking “OK” will bring up the next dialog to choose a database connection where you’ll select the <strong>New Connection</strong> button:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ6R1NEnhMTmgXbyVjwHsxeTBt2_IzZESWbjNHSTcVbFY1kEs23NhEUPxyhOAhiu-J5RlXL69Qh1fh1Bk-JZ4s_Kj27Xnhgaiw3cMeaekuP0sDNf1W4rYe4-6U3J0eIiZTOYeTapSoqPwB/s1600-h/2010-12-01_232107%5B2%5D.png"><img alt="2010-12-01_232107" border="0" height="64" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRSk-DbjI/AAAAAAAAAMM/TWF2nosz4BY/2010-12-01_232107_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232107" width="244" /></a><br />
</li>
<li>In the Add Connection dialog specify the name of the SQL server – this can be (local) if SQL (or SQL Express) is installed on the same machine you’re working on or another machine:<br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRSyP7udI/AAAAAAAAAMQ/VvKjtyx6J8Y/s1600-h/2010-12-01_232132%5B2%5D.png"><img alt="2010-12-01_232132" border="0" height="244" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRTG_ORZI/AAAAAAAAAMU/8ToyoMo-mEk/2010-12-01_232132_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232132" width="168" /></a><br />
For (local) machines you should be able to the leave the <strong>Log on to the server</strong> default as <strong>Use Windows Authentication</strong>. For remote machines you might have to switch to <strong>Use SQL Server Authentication</strong> and supply a user name / password combination – unless your machine is part of a Windows domain as is usually the case in corporate environments. The selected database name should be <strong>AdventureWorksDW2008</strong> or <strong>AdventureWorksDW2008R2</strong> depending on which version you installed.<br />
</li>
<li>Press the Test Connection button to verify that these settings work. If the test fails seek help or otherwise resolve the problem before continuing.<br />
<a href="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRTUw7x2I/AAAAAAAAAMY/rhN8AHbbfYI/s1600-h/2010-12-01_232206%5B2%5D.png"><img alt="2010-12-01_232206" border="0" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFNh3JAVheolmrKKy_FgmBSjGYVG34KzFSd2qLzjAazpdm58bR77X72_78r64wBJQ0bEkaias0l69KNBn_CnruZ9C9OdkEGSJw3l5ADACy2Z-JNVcp2mlqDIgpRXVS39LcVUcpdlpYXQCr/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232206" width="244" /></a><br />
</li>
<li>Save the Connection string and continue:<br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRUKqeZEI/AAAAAAAAAMg/XePmvpxAxaY/s1600-h/2010-12-01_232243%5B2%5D.png"><img alt="2010-12-01_232243" border="0" height="197" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRUeDtC1I/AAAAAAAAAMk/Jytd3Wqd4t0/2010-12-01_232243_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232243" width="244" /></a><br />
</li>
<li>Choose the <strong>DimCustomer</strong> table for the Select statement:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQVRUiqFcVI/AAAAAAAAAMo/ON8BRzphcAs/s1600-h/2010-12-01_232304%5B2%5D.png"><img alt="2010-12-01_232304" border="0" height="188" src="http://lh5.ggpht.com/_BvH8o_BvG-4/TQVRVCTTQ-I/AAAAAAAAAMs/B4LE0PTyw3w/2010-12-01_232304_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232304" width="244" /></a><br />
</li>
<li>Choose <strong>FirstName</strong>, <strong>MiddleName</strong>, <strong>LastName</strong>, <strong>BirthDate</strong>, <strong>Gender</strong>, and <strong>Phone</strong> for columns and click the <strong><u>W</u>HERE</strong>… button:<br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQVRVHVDxWI/AAAAAAAAAMw/Fmh1Qyun6uQ/s1600-h/2010-12-01_232340%5B2%5D.png"><img alt="2010-12-01_232340" border="0" height="125" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRVt7DkPI/AAAAAAAAAM0/laAna2HhAn0/2010-12-01_232340_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232340" width="244" /></a><br />
</li>
<li>Select the <strong>CustomerKey</strong> as the Column name to filter on, specify <strong>Form</strong> as the source (i.e. use Request.Form collection value) then type the name previously used as the ID for the Textbox control in <a href="http://pragmatic-software.blogspot.com/2010/12/how-to-build-2-tier-aspnet-web-sitepart.html#addtextbox">step 5</a>:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRVzn2x7I/AAAAAAAAAM4/PITrJxkG47c/s1600-h/2010-12-01_232408%5B2%5D.png"><img alt="2010-12-01_232408" border="0" height="142" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRWM7S-3I/AAAAAAAAAM8/otHxx_EPez4/2010-12-01_232408_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232408" width="244" /></a><br />
</li>
<li>After clicking the Add button you’ll see the WHERE clause that has been constructed and you can click Test Query to verify that the SELECT statement executes properly as expected:<br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRWeJJ5fI/AAAAAAAAANA/y7-0HDVCjjM/s1600-h/2010-12-01_232425%5B2%5D.png"><img alt="2010-12-01_232425" border="0" height="78" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJjuwegFg_IY7PzjW_n69ODoXNaWDyYfnyQdTZwjMzZsMOw6BA4GkW5u9T6K2IUR-1F4MSg0-ybuqmPOcx0RsiT5A_VAUwLJw2momUKKzeXzghuyg3rlc174-hRHqP87v9B76NnYoKuNqN/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232425" width="244" /></a><br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQVRWoOJamI/AAAAAAAAANI/pckXuAb8ikM/s1600-h/2010-12-01_232444%5B2%5D.png"><img alt="2010-12-01_232444" border="0" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzdP8LqDa0LR5dmXx-MrTGBisxFlUyL-IpvotJmTARNkLMeq350V9w0nuX99-isQPSRsS4QC4F9C7qpiBJEzxsSMLHUi4JLNz9iw7jTkOj80j7IkbuTKfcl7TQQAsGg1yzB-afDfwAQnTt/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232444" width="244" /></a><br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQVRXVf2w8I/AAAAAAAAANQ/AIDe16oZIqs/s1600-h/2010-12-01_232456%5B2%5D.png"><img alt="2010-12-01_232456" border="0" height="164" src="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRXiiw7wI/AAAAAAAAANU/dyKc-uS47TU/2010-12-01_232456_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232456" width="244" /></a><br />
<a href="http://lh5.ggpht.com/_BvH8o_BvG-4/TQVRX5_AJ9I/AAAAAAAAANY/n6T82G-fPuo/s1600-h/2010-12-01_232508%5B2%5D.png"><img alt="2010-12-01_232508" border="0" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUIhFDunxi4JcKqyQ1YbCLSKNRExfbyVkJrAqouhNHyWb1mPBGhIX6I1XlJkXUMh4sCnSk9boXRty-IU21F13uQ3l0SOAor0YW-2MDYP12mPOjw3iI0kVQLjqfX73x7nIcckcPY54Sonxr/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232508" width="244" /></a><br />
</li>
<li>After clicking the Add button you’ll see the WHERE clause that has been constructed and you can click Test Query to verify that the SELECT statement executes properly as expected:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRYxdS7ZI/AAAAAAAAANg/TzRYjloNBZY/s1600-h/2010-12-01_232531%5B2%5D.png"><img alt="2010-12-01_232531" border="0" height="175" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRZUrXGZI/AAAAAAAAANk/m5IIBsDNWT4/2010-12-01_232531_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232531" width="244" /></a><br />
</li>
<li>Save your work then move back to Default.aspx to wire the Submit button to post back to the new Result.aspx page:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Kblt1DE9tnyPZ5S11Hmw9kf01kqQdiUtdOz_pnem1Gf1PvXLTE7KJ9EzaCX_-LJMNI2PHUOwaN_nehuTVuaDtKNu3YM00moHrXcv0jS-sLy0-PF2ulpkU6rngmn9QKoEzZy4TZylG02R/s1600-h/2010-12-01_232823%5B2%5D.png"><img alt="2010-12-01_232823" border="0" height="103" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRZrRPJRI/AAAAAAAAANs/sCc65kvMPQA/2010-12-01_232823_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232823" width="244" /></a><br />
Clicking the ellipsis next to the <strong>PostBackUrl</strong> brings up a list of pages within the project where you can select <strong>Result.aspx</strong>:<br />
<a href="http://lh4.ggpht.com/_BvH8o_BvG-4/TQVRaPneA_I/AAAAAAAAANw/78i5y5yvIxQ/s1600-h/2010-12-01_232832%5B2%5D.png"><img alt="2010-12-01_232832" border="0" height="149" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRacVXM8I/AAAAAAAAAN0/Qu3BfQBAH10/2010-12-01_232832_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232832" width="244" /></a><br />
</li>
<li>Right-click on <strong>Default.aspx</strong> in Solution Explorer and set it as the start page:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBHJ-lxsYW8eoz3DWRzfvd8y57SQRKB2f4NzczfWBzsKrVLdIaSlv-EUkatXUvgTcmMP9nmJLO-TjlyLgEZ5E_vHaJgAMItOogG-dKtlKdkhaAVQl0L8mzAqPpxCExEq7lrOSHtrHClsOt/s1600-h/2010-12-01_232659%5B2%5D.png"><img alt="2010-12-01_232659" border="0" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgijTWQuqwfHYURL3aazvZljPHMFufjfPAwh0pxRS-JAPpvM2sb86krnXmExok1J61pnJjhJSvlG5l7jJqz3TfcU9eSMUd_U8SFYABT7fEj_X-rEYoR54MxlSGVjrLiOkMMClHoKYw_gX1M/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232659" width="244" /></a><br />
</li>
<li>Finally, hit “F5” to test the site:<br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRbBM5i9I/AAAAAAAAAOA/p5H9zUeSd-o/s1600-h/2010-12-01_232735%5B2%5D.png"><img alt="2010-12-01_232735" border="0" height="143" src="http://lh6.ggpht.com/_BvH8o_BvG-4/TQVRbRzf_mI/AAAAAAAAAOE/S6NrT4TClFk/2010-12-01_232735_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232735" width="244" /></a><br />
<a href="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRbt2reEI/AAAAAAAAAOI/oyzMzqlsVZg/s1600-h/2010-12-01_232859%5B2%5D.png"><img alt="2010-12-01_232859" border="0" height="93" src="http://lh3.ggpht.com/_BvH8o_BvG-4/TQVRb6OeO9I/AAAAAAAAAOM/MeCMIchht_I/2010-12-01_232859_thumb.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="2010-12-01_232859" width="244" /></a></li>
</ol><br />
Note the following:<br />
<br />
<ul><li>The port number shown above (:1483) will be different – Visual Studio generates a random port number for each web project.</li>
<li>Visual Studio contains (hosts) a built-in “mini” web server functionally identical to the full-blown web server IIS (Internet Information Server). However, this server is restricted to a minimum number of browser connections and can only be accessed via a web browser on the same machine Visual Studio is on.</li>
</ul><br />
<div><br />
</div><br />
At this point we’ve got a working 2-tier ASP.NET 4.0 web site that’s prompting for a customer, querying a SQL database and displaying the results in a grid (tabular) format. Next we’ll setup IIS 7.5 on Windows 7 then deploy the site out to a commercial web server.Unknownnoreply@blogger.com0