[ HomeContact ]   

NOTE PAGES*

this page was last updated: 05/23/2013 11:40:31 AM

C# ASP.NET - Code Nuggets

12/18/11

PROBLEM: Notes regarding C# coding solutions have become unwieldy.

SOLUTION: Move elements from this notes page to KeyTap Project Manager.

Here is a copy of the current list (12/18/11) available at KeyTap Project Manager : Code Nuggets :

ID Category Title
202 | nug |   C# ASP.NET : C# : AND OR logical operators
241 | nug |   C# ASP.NET : C# : CheckBox
254 | nug |   C# ASP.NET : C# : CheckBox : bind to database
191 | nug |   C# ASP.NET : C# : DataGrid formatting
207 | nug |   C# ASP.NET : C# : If equals / does not equal
206 | nug |   C# ASP.NET : C# : If true/false
286 | nug |   C# ASP.NET : C# : ListBox : CAVEAT
198 | nug |   C# ASP.NET : C# : password generator
180 | nug |   C# ASP.NET : C# : table single cell (field) reference
284 | nug |   C# ASP.NET : C# : Timestamp AddHours (to page)
253 | nug |   C# ASP.NET : C# : trace
203 | nug |   C# ASP.NET : C# : Trim() remove trailing spaces
108 | nug |   C# ASP.NET : MySql : CONVERT from Sql Server & Access
255 | nug |   C# ASP.NET : MySql : COUNT
285 | nug |   C# ASP.NET : MySql : DATE_ADD
240 | nug |   C# ASP.NET : Sql Server : case sensitive select
283 | nug |   C# ASP.NET : Sql Server : DATEADD
249 | nug |   C# ASP.NET : Sql Server : greater than, less than, BETWEEN
182 | nug |   C# ASP.NET : Sql Server : Inserts
247 | nug |   MS Access : go to last record
248 | nug |   MS Access : go to new record
250 | nug |   MS Access : open form in datasheet view
181 | nug |   MS Access : sort simple text list
213 | nug |   Sql Server : Endico WinHost Settings
214 | nug |   Sql Server : KeyTap pubMemos


Wow! That copy/paste from IE web browser sure worked nice.

Only had to add "_top" and fix some code at KeyTap Project Manager.

 

C# ASP.NET - Validation of viewstate MAC failed.

11/13/11

PROBLEM: During an extended coding session setting up an online memo database to replace my system destroyed by Apple's last OS upgrade, an exception was raised when I selected a category from a ListBox that I had left open on my phone for awhile. Several hours online provided only sketchy information, and the suggestions seemed to me totally absurd, "In your web.config file, disable these services on the site by way of "false" this and "never" that. I narrowed the behavior down to happening only after a page had been left open unattended for some time. The error message read in part:

Server Error in '/' Application.

Validation of viewstate MAC failed. If this application is hosted by a Web Farm
or cluster, ensure that <machineKey> configuration specifies the same
validationKey and validation algorithm. AutoGenerate cannot be used in a
cluster.

SOLUTION: Finally, I found a strong statement at the bottom of some forum paraphrased by, "Why don't you read all the posts? I already answered this for you, and all these other suggestions are just half measure work arounds, and are truly strong security risks. Fix the problem... and do it safely." Tracking back up the postings, I found they had in fact answered correctly. However, it still took me some stitching together of various bits of information, because I never did find a succinct example of just where in the web.config I should put the machine key which could be generated by any number of sites. Therefore, so I never forget, here is an example of it just exactly (more or less) what I put in the web.config file of each of my sites (of course WITHOUT the actual generated 128 and 64 character keys generated individually for each) :

 <system.web>
          <!-- 11/12/11: -BF, Below are machine keys generated at http://aspnetresources.com/tools/machineKey -->
          <machineKey validationKey="...SOMEREALLYREALLYLONGNUMBEROFCHARACTERS...."
                                   decryptionKey="...ALESSLONGNUMBEROFCHARACTERS...."
                                   validation="SHA1"
                                  decryption="AES" />
</system.web>

Worked like a charm, and it makes me want to track down and slap the shit out of all the "experts" telling me to drop some very basic security settings with their "set such and such to 'false' and another thing to 'never', and I choose not to repeat the exact snippets in order to save people running across them once again and assuming that greater numbers of instances indicates a more correct answer.

 

C# ASP.NET reference DataTable vs DataSet row / column directly

11/10/11

PROBLEM: after success adding line breaks to row column cell, still confused regarding referencing DataTable directly as opposed to within a DataSet - online references generally use DataSet if not full out Visual Studio type "help"

SOLUTION: my own edification

adapter.Fill(myTable);


// ok (from MSDN)
//   For each table in the DataSet, print the values of each row.
//
//         foreach(DataTable thisTable in myDataSet.Tables){
//           For each row, print the values of each column.
//                    foreach(DataRow myRow in thisTable.Rows){
//                          foreach(DataColumn myCol in thisTable.Columns){
//                               Response.Write(myRow[myCol]);
//                        }
//                  }
//              }


// ok
//   For each row, print the values of each column.
//        foreach(DataRow myRow in myTable.Rows){
//              foreach(DataColumn myCol in myTable.Columns){
//                    Response.Write(myRow[myCol]);
//              }
//        }
 

// ok
//    foreach(DataColumn myCol in myTable.Columns) {
//        Response.Write(myCol+"<br/>");
//    }


// ERR - EXCEPTION THROWN
// Response.Write(myTable.Rows[myCol]);


// ok
// Response.Write(myTable.Rows[0]["ID"]);


// ok
// Response.Write(myTable.Rows[0]    ["ID"]);


// ok
//    foreach(DataRow myRow in myTable.Rows){
//        Response.Write(myTable.Rows[0]["ID"]+"<br/>");
//    }
//


// ok
//    foreach(DataRow MOTHERFUCKINGSHITFUCKER in myTable.Rows){
//        Response.Write(myTable.Rows[0]["ID"]+"<br/>");
//    }
//
// apparently myRow can be anything though MOTHERFUCKING-SHIT-FUCKER did return error


// ok
// Response.Write(myTable.Rows[0]["Unit"]+"<br/>");
// Response.Write(myTable.Rows[1]["Unit"]+"<br/>");


// ok
// Response.Write(myTable.Rows[0]["ID"]+" "+myTable.Rows[0]["Unit"]+"<br/>");


// ok
// Response.Write(myTable.Columns[0]);
 

// ERR - EXCEPTION THROWN
// Response.Write(myTable.Columns[0][0]);
//
// Compiler Error Message:
// CS0021: Cannot apply indexing with [] to an expression of type 'System.Data.DataColumn'
 

// ERR - EXCEPTION THROWN
// Response.Write(myTable.Columns["Unit"][0]);
//
// Compiler Error Message: CS0021:
// Cannot apply indexing with [] to an expression of type 'System.Data.DataColumn'


// ok (as review)
// Response.Write(myTable.Rows[0]["ID"]);


// compare all previous as apposed to such as (careful with closing parenthesis) following
// ok
// adapter.Fill(myDataSet);
// Response.Write(myDataSet.Tables[0].Rows[0]["ID"].ToString());
// Response.Write(myDataSet.Tables[0].Rows[0]["Memo"].ToString().Replace("\r\n", "\r\n<br/>"));

 

C# ASP.NET Sql Server variable select string (to extend without rewriting full string)

10/28/11

PROBLEM: Endico ListBox was showing a fewer number of paintings for selection "Miscellaneous" than were displayed on the ListingInStyle page. On trying to port over the code from the ListingPage exceptions were thrown due to slight syntax incompatibilities (even before trying to port code over to MySql version)

SOLUTION: Ponder this  (which worked for the listing page):

                                                                                                              "WHERE (xtnd_code = '"+styleCode+"' "+toggleMSC+")
vs this (which worked for the listing page):

 DataRow[] rowCount = tblCountPaintings.Select("xtnd_code Like '"+strCategorySelected+"' "+toggleMSC+"");

And ponder this (which worked for the listing page):

if (styleCode == "MSC")
{
                toggleMSC = "OR pubMSC = '1'";
} else {
                 toggleMSC = ""; }

 vs this (which was what worked for the ListBox):

 if ( dsCategories.Tables[0].Rows[x] ["SelectCategoryQuery"].ToString() == "MSC" )
{
                  toggleMSC = " OR pubMSC = 1";
} else {
                  toggleMSC = "";
}

and of course MySql needed to see this slight alteration (1 to True (no quotes):

if ( dsCategories.Tables[0].Rows[x] ["SelectCategoryQuery"].ToString() == "MSC" )
{
                   toggleMSC = " OR pubMSC = True";
} else {
                   toggleMSC = "";
}
 

If I am not mistaken, the promise of C# ASP.NET was supposed to be: code once, use it everywhere... right.

 

C# ASP.NET filtering dataset table

10/27/11

PROBLEM: After adding a dynamically displayed number for the paintings found in each category on the Endico named style selection list, the list elements required filtering in case "0" paintings were ever available in a given category. Removing zero returns enhances user experience.

SOLUTION: Records within a table within a dataset can be manipulated just as well as the original Sql Server data source, though finding the correct syntax took more than seven hours.

dsCategories.Tables[0].Rows[x].Delete();

- where "0" points to the first table in the dataset, while 'x' is the row pointer variable into which the specific number will be filled by a "foreach" statement

Here is the environment in which that single statement line found its home:

 // count paintings per category and concatentate for ListBox
int x = 0;
foreach (DataRow row in dsCategories.Tables[0].Rows)
{
   strCategorySelected = dsCategories.Tables[0].Rows[x] ["SelectCategoryQuery"].ToString();
   DataRow[] rowCount = tblCountPaintings.Select("xtnd_code Like '"+strCategorySelected+"'");
   strCountCategory = rowCount.Length.ToString();
   dsCategories.Tables[0].Rows[x]["SelectCategory"] = dsCategories.Tables[0].Rows[x]  ["SelectCategory"]+" "+
   "\u00A0\u00A0("+strCountCategory+")\u00A0\u00A0";
          if (strCountCategory == "0") { dsCategories.Tables[0].Rows[x].Delete(); }
                    x = x+1;
   } //END foreach

Here's a link to the code in action (notice there are no zero return selections): CLICK

EVEN EASIER: DataTable in memory can be queried using exactly same SQL syntax as used for a Sql Server table on the server, such as:

 cmd.CommandText = "SELECT ListItem, RideStatus, SortOrd "+
"FROM myServerTable "+
"WHERE (RideStatus = 1) "+
"ORDER BY SortOrd ASC;";

adapter.SelectCommand = cmd;
adapter.Fill(myDataTableInMemory);

string myString = myDataTableInMemory.Rows[0] ["RideStatus"].ToString();

 

C# ASP.NET Sql Server scalar does not work with MySql

10/21/11

PROBLEM: Scalar that counts stock to display a "MORE" link does not function as expected in MySql after Sql Server pages are ported over.

SOLUTION: Change variable type from 'int' to 'long' (in two places) and remove space between COUNT and (field_name).

 Sql Server accepts the following:

int countStock;

// count stock and toggle MORE
cmd.CommandText = "SELECT COUNT (img_num) "+
                                      "FROM t_infimg "+
                                     "WHERE (xtnd_code = '"+styleCode+"' "+toggleMSC+") "+
                                          "AND pubStatus = 'STOCK' AND publish = '1' ";

conn.Open();
countStock = (int) cmd.ExecuteScalar();
conn.Close();

 

 MySql requires the following changes (marked in BLUE):

long countStock;

// count stock and toggle MORE
cmd.CommandText = "SELECT COUNT(img_num) "+
                                      "FROM t_infimg "+
                                     "WHERE (xtnd_code = '"+styleCode+"' "+toggleMSC+") "+
                                          "AND pubStatus = 'STOCK' AND publish = '1' ";

conn.Open();
countStock = (long) cmd.ExecuteScalar();
conn.Close();

Total of 3 changes: 'int' to 'long' in two places, remove space between COUNT and (img_num)

Generic includes with mapped root at runtime

10/15/11

NOTE: The following problem was fixed by the the newest patch for Expression Web 4 but has been left here just in case.

PROBLEM: Code blocks of HTML with references to root using "/" do work on the server but expect the destination to be found in "wwwroot" on the development laptop. Therefore a way is required to insert variable text in generic headers and footers making them portable into folders at various levels of nesting with minimal alteration. Also, while the pointer "~" does does in fact function in a C# code block, it does not work in an HTML tagwhere only such as ".." or "../../.." will do the trick.

SOLUTION: Nest variable path statements in each include page to be controlled by a single statement in the Page_Load() block of the page which calls it.

Cascading style sheets (CSS) were tested as a possible answer to this root directory problem but proved worse than no answer at all. Very soon the same problem arose but this time with absolutely no possibility of a solution.

Also Visual  Web Developer was tested and found to be inappropriate having no significant advantages over Frontpage 2003.

Previously Dreamweaver was also rejected.

Hand coding is still the best way to go designing functional websites targeted for a Post-TweetieFace world.

Therefore, inside a script block (without a Page_Load event) within each include file define necessary strings for mapping to root path (for the file itself ,and for all contained sub includes). For example a main page with header might contain these definitions:

string rootPathPage;
string rootPathHeader;
string rootPathHeaderSub;
string rootPathMainMenu;

In sub includes (unless working on that file by itself) comment out the required subset of these definitions. For example, the sub header will need to have enabled "rootPathHeaderSub" if opening that file directly by itself, though the same string definition will be in conflict with the same definition sent by an upper level containing page that will feed it parameters (such as: "../../") when that upper level page is opened and calls the sub include.

place inline code into HTML where needed using the following syntax:

<%=rootPathPage%>
<%=rootPathHeader%>
<%=rootPathHeaderSub%>
<%=rootPathMainMenu%>

for example:

background="<%=rootPathHeaderSub%>images/bakgrd.jpg"

set values in Page_Load() of the calling page thus:

 private void Page_Load (object sender, EventArgs e)
{

rootPathPage = "../../";
rootPathHeader = rootPathPage;
rootPathHeaderSub = rootPathPage;
rootPathMainMenu = rootPathPage;

 

While working through upgrading all pages to this process, all headers, footers, and include pages on the Endico website will be defined in this way using "Dev" versions of the files, and only after all pages have been redirected to the "Dev" versions and tested fully will the production version of the includes be updated and the main pages  redirected back to them. Thus both systems will run concurrently for a time... maybe a long time.

 

Includes not refreshing after edit

10/10/11

PROBLEM: When pages were moved to new hosting service away from co-located server, includes stopped refreshing after being edited. Each aspx page holding an include would have to be edited itself in order to refresh its includes. Frontpage is no longer supported and aspx pages only refresh their FP style includes at compile time after the page holding the include has itself been altered, probably along with every level of nested include.

SOLUTION: Change all include statements to the new much simpler syntax below.  Any subsequently altered include pages will update correctly at each run time.

 
<!-- #include file="/myFolder/myIncludeFile.aspx" -->
 

The "/" at head of file name causes relative reference all the way back to root. Frontpage always took care of this transparently. Finally figured out how to fix this (vs ~/etc) from reading article: here
 

DOWNSIDE: The include file will no longer display along with its holder page in Frontpage, so no more full WYSIWYG editing.

Note: Make sure all relative references start at root ("/") else nested includes will look relative to current page directory, (i.e.: "../images/myPic.jpg" will fail if page is loaded not from "/gallery/" but from "/gallery/mus/"). Frontpage always took care of this on its own (even when files were moved among folders) without bothering anybody about it.

Further Notes: Files that are copied via Windows explorer onto K6 (a Win 7 computer) expand include directives by replacing the include webbot directive with the relevant html inside a checksum block. If files are first altered in Frontpage (version used for WinHost online publication) to the simpler include syntax (above) subsequent copy/paste to K6 does not have the checksum blocks, but retains the simpler include directive only.

 

Batch File Does Not Run by clicking icon in Windows Explorer

04/09/11

PROBLEM: MyBatch.bat runs correctly from DOS prompt command line, but just blinks and fails with no notification if double clicking its icon (or Right Click/Open) in Windows Explorer

SOLUTION: change suffix from .bat > .cmd

 MyBatch.bat        (doesn't work)
 MyBatch.cmd      (same file, different suffix, works fine under Windows Xp Pro)

 

Toggle Color Prompt for Qualified Horses Equipoise DataGrid

01/09/11

PROBLEM: New active checkbox easily confused with static "Qual" checkmark, so enabling programmatically applied green background to selection cells.

SOLUTION: Of course, examples of syntax found online proved wrong, so here are the notes (in order) stepping toward functional code. [copy/paste snippets into notepad and they will expand to full line]:

 // ok
//myDataGrid.Items[5].Cells[11].BackColor = System.Drawing.Color.Green;

// ok
//string test = tblHorses.Rows[0] ["RecNum"].ToString();
//int intTest = tblHorses.Rows.Count;

// ok
//for (int i = 0; i < myDataGrid.Items.Count; i++) { myDataGrid.Items[i].Cells[11].BackColor = System.Drawing.Color.Green; }
for (int i = 0; i < tblHorses.Rows.Count; i++) { if (tblHorses.Rows[i] ["isQualified"].ToString() == "True")
{ myDataGrid.Items[i].Cells[0].BackColor = System.Drawing.Color.PaleGreen; }
}

 

Adding Checkbox toggles to Equipoise DataGrid

01/01/11

PROBLEM: startup copy/paste DataGrid and sample CheckBox code results in grid not displaying
SOLUTION: copy/paste code to appropriate locations and assign bind

  1. code for submit button click must be inside of page load, but outside of !IsPostback

  2. bind and adjust field names Sql & Datagrid (keep pub_id until certain of function)

  3. add html header script

 

Bob's Naming Conventions

12/23/10:  Bob uses variable and object naming thus -

txtTextBox
lbxListBox
btnButton
chkCheckBox
rblRadioButtonList
lblLabel
litLiteral

This means nothing to anybody else, but a note needs to be placed somewhere so that Bob can toss out a little yellow post-em, and this is that somewhere .

 

Get Server Variables to feed into Web Usage Logs

// complete list of ServerVariables at: http://msdn.microsoft.com/en-us/library/ms524602.aspx
string strIP = Request.ServerVariables["REMOTE_HOST"];
string strBrowser_type = Request.ServerVariables["HTTP_USER_AGENT"];

Paging Properties

12/03/10

in asp:Datagrid def:

AllowPaging="True"
PageSize="10"

as member inside datagrid def (as apposed to Columns, HeaderStyle)

<PagerStyle
Mode="NumericPages"
HorizontalAlign="Center"
Position="TopAndBottom" >
</PagerStyle>

Getting something out of a table in memory

11/27/10

Currently not required in Equipoise:  //dsCategories.Tables[0].Rows[0].AcceptChanges();
Due: changes initiated without, but don't forget this exists

11/24/10

PROBLEM: load DataSet (or DataTable) for the drop-down list for Equipoise once, and once only
                     and use table in memory for triggering prompts for search selection event results
SOLUTION: use ViewState

include in @ Page directive <@Page %>  statement EnableViewState="True" such as:

<%@ Page Language="C#" Debug="True" EnableViewState="True" %>

initiate before page load such as:

DataSet myDataSet = new DataSet();
string myString;

inside Page_Load method include inside if (!IsPostBack) section such as:

adapter.SelectCommand = cmd;
adapter.Fill (myDataSet);
ViewState["dsCategories"] = myDataSet;

reference from other methods thus:

myDataSet = (DataSet)ViewState["myData"];
strMyString = myDataSet.Tables[0].Rows[0] ["myColumnName"].ToString();

Aside:

/////// PREVIOUS Google FINDS for START TEST FOR GETTING SINGLE CELL TABLE RETURN ///

     // Find SelectCategoryQuery Prompt value
     tblCategories.DefaultView.Sort = "SelectCategoryQuery";
     int FoundRow = tblCategories.DefaultView.Find("CT%");
     tblCategories.DefaultView[FoundRow] ["SelectCategoryQuery"] = "CT%";
      if FoundRow(!= -1) { lblGrabTableCell.Text = FoundRow.ToString(); }

/////// END PREVIOUS Google FINDS for TEST FOR GETTING SINGLE CELL TABLE RETURN /////

//ok //tblCategories = (DataTable)ViewState["tblCategories"];
        //tblCategories.DefaultView.Sort = "SelectCategoryQuery";
       //int FoundRow = tblCategories.DefaultView.Find("CT%");
       //strCategory = tblCategories.Rows[FoundRow] ["SelectCategoryPrompt"].ToString();

//ok //tblCategories = (DataTable)ViewState["tblCategories"];
        //tblCategories.DefaultView.Sort = "SelectCategoryQuery";
        //string HorseQuery = lbxCategories.SelectedItem.Value;
        //int FoundRow = tblCategories.DefaultView.Find(HorseQuery);
       //strCategory = tblCategories.Rows[FoundRow+1] ["SelectCategoryPrompt"].ToString();

//ok //DataSet dsCategories = new DataSet();
       //dsCategories = (DataSet)ViewState["dsCategories"];
       //DataRow[] row = dsCategories.Tables[0].Select("SelectCategoryQuery Like 'CT%'");
       //strCategory = row[0] ["SelectCategoryPrompt"].ToString();

final:

DataSet dsCategories = new DataSet();
dsCategories = (DataSet)ViewState["dsCategories"];
string Test = "CT%";
DataRow[] row = dsCategories.Tables[0].Select("SelectCategoryQuery Like '"+lbxCategories.SelectedItem.Value+"'");
strCategory = row[0] ["SelectCategoryPrompt"].ToString();

 

Migrating Sql Server to MySql (the Wiki)

11/12/10

PROBLEM: Sql Server tables to be moved to MySql on a new system
SOLUTION: here are my quick notes (maybe valuable only to myself) for the final steps
                      required in order to get existing C# ASP.NET aspx pages talking to MySql

Note: I personally do not use code behind, but maintain code and html in the same file ala Java,
           and I have succeeded in that manner with such as: endico.com, which at one time I successfully
           move from Sql to MySql with very minimal effort... once the MySql setup and connection succeeded

CAVEAT: Do not involve FrontPage in this due to amount of "help" it provides changing underlying code.
                    Merely copy files over in-place and edit by hand.

Global changes to aspx pages assuming successful setup of MySql on new system

1) keep intact same name of web.config connection but changing its connection string
    to MySql specific connection string (correct examples exist online)


2) place "MySql.Data.dll" in website's root directory /bin folder (create folder if does not exist)


Do the following (4 steps) on each aspx page (copied from original Sql Server web site)

1)  keep track of which pages have been migrated by changing page title
     such as: <!-- "File: whatever.aspx" -->
               to: <!-- "MySql File: whatever.aspx" -->


2) System.Data.SqlClient > MySql.Data.MySqlClient 


3) Find/Replace occurrences in object names: Sql > MySql   
(Caveat: do not change in cases where is part of ref to a named
               database field such as 'hasSQLImageOnline')


4) Find/Replace Boolean Sql Server references:  '0' > 'False'  
                                                                                    '1' > 'True' 

11/07/11: Whoops! New Access --> MySql converters obsolete need for '1'  >  'True', still leave note here in case
                 Plus the following CAVEAT may just be waiting to bite me in the hind quarters

    CAVEAT: Such Booleans are not always offset by single quotes
                         look for such as:      pubCompare = 1
                                     becomes:      
pubCompare = 'True'   (note single quotes)

                                                  or:      WHERE (privViewing=1)
                                     becomes:       
priViewing = 'True' 

                                                 or:        publish = 1
                                     becomes: 
      publish = 'True'      

           * Must have single quotes for 'True'




Done. Run.



Except maybe (Sql vs MySql cast):

1) Sql Server accepts the following in a SELECT string which
will allow inserting an "NFS" (Not For Sale) in presentation
of a price field:

     '$'+CAST(price AS VARCHAR(9))+'.00' AS priceText,


But MySql accomplishes the same cast thus:

     CONCAT('$', CAST(price AS CHAR), '.00') AS priceText,

As for concatination:

"SELECT ID, Category, (Category + '  ' + pubName) AS lstCategory"

becomes -

"SELECT ID, Category, CONCAT(Category,  '  ',  pubName) AS lstCategory "

Except also maybe (Sql vs MySql random)

cmd.CommandText = "SELECT top 12 *"+
"FROM tbl "+
"WHERE publish = '1' ORDER BY NEWID() ";

becomes (while removing "top 12"):

 cmd.CommandText = "SELECT *"+
"FROM tbl "+
"WHERE publish = 'TRUE' ORDER BY RAND() LIMIT 12";
 

 There is also the little matter of scalars and counts for which Sql Server accepts the following:

int countStock;

// count stock and toggle MORE
cmd.CommandText = "SELECT COUNT (img_num) "+
                                      "FROM t_infimg "+
                                     "WHERE (xtnd_code = '"+styleCode+"' "+toggleMSC+") "+
                                          "AND pubStatus = 'STOCK' AND publish = '1' ";

conn.Open();
countStock = (int) cmd.ExecuteScalar();
conn.Close();

 

 but MySql requires the following changes (marked in BLUE):

long countStock;

// count stock and toggle MORE
cmd.CommandText = "SELECT COUNT(img_num) "+
                                      "FROM t_infimg "+
                                     "WHERE (xtnd_code = '"+styleCode+"' "+toggleMSC+") "+
                                          "AND pubStatus = 'STOCK' AND publish = '1' ";

conn.Open();
countStock = (long) cmd.ExecuteScalar();
conn.Close();

Total of 3 changes: 'int' to 'long' in two places, remove space between COUNT and (img_num)

 
11/24/11: Oops, sorry. Found this during most recent port pubMemo to MySql:

getdate() > Now()

where placed on 2 lines Sql Server ver:

"WHERE RandomID = "+intRandomID.ToString()+""+
"ORDER BY Category, Title ASC";

must be moved to 1 line thus:

"WHERE RandomID = "+intRandomID.ToString()+" ORDER BY Category, Title ASC";


As an aside for debugging put this at the bottom of page html:

     <asp:Literal id="Literal1" Text="Oh, oh. Code failure!!" runat="server"/><br/>&nbsp;<br/>  


Then step this line by line top to bottom through code:

Literal1.Text = "Moveable: A-Ok"; //TEST  

The Literal will default to Text="Oh, oh..." at point of failure


********** END MYSQL WIKI **********
 

Static IP Secret

11/12/10

PROBLEM: What is the difference between Microsoft Sql Server and MySql
SOLUTION: click for the simple comparison

10/30/10

PROBLEM: local computer Internet access fails after setting static IP
SOLUTION: set DNS Servers appropriately

find number using local Router Status page, or
set computer to "Obtain an IP address automatically"
   Start/Settings/Network Connections/Local Area Connection/Properties/Internet Protocol (TCP/IP)
ipconfig /all
use DNS Servers provided by Internet Access Provider
 

Snippet Repository


[08/28/10]
C# ASP.NET variable HTML IF/THEN include text with Response.WriteFile controlled within SCRIPT TAGS


<script runat="server">

string CommentaryOn;
string CommentaryFilePrefix;
string CommentaryFileNumber;
string CommentaryFileSuffix;


public void Page_Load(object sender, EventArgs e){


CommentaryOn = "Yes";
CommentaryFilePrefix = "Ch";
CommentaryFileNumber = "0001";
CommentaryFileSuffix = "Commentary.aspx";

}
</script>

<html>
<body>

 <% if (CommentaryOn == "Yes") { %>

<% Response.WriteFile(CommentaryFilePrefix+
CommentaryFileNumber+CommentaryFileSuffix); %> <br/><br/>


<% } else {%>

<!--- //null --->

<%} %>

</body>
</html>


above due Response.WriteFile will not accept variable within quotes, therefore, toggling text "off"
cannot be handled by referencing a separate blank page, note how C# are interleaved with standard html
[08/28/10]


/Xml line break
&lt;br/&gt; 

//Xml italic
&lt;i&gt; 

<!-- INCLUDE NAVBAR -->
<% Response.WriteFile ("footer.htm"); %>
<!-------------------->

<base target="main">

<body stylesrc=../../style01.htm>

int MyInt = Convert.ToInt32(newString);

 SqlDataAdapter objAdapter = new SqlDataAdapter(strSQLforGrid, objConnection);
DataTable myTable = new DataTable("MyTable");
objAdapter.Fill(myTable);
objConnection.Close();

// pubCustomerID below is a named column
//example of accessing cell in DataTable
//example of accessing field in DataTable
string CustID = myTable.Rows[0] ["pubCustomerID"].ToString();

//example of accessing cell in DataSet
//example of accessing field in DataSet
paintingID = dsFile.Tables[0].Rows[0] ["ImageUrl"].ToString();

// NOTE: observe closely the use of period and space
// separators and how they differ between DataTable and DataSet

 // assign paintings displayed count to header label
// strCount = dlPaintings.Items.Count.ToString();

 //strCountAll = dgHorses.Items.Count.ToString();
 //strCountAll = tblHorses.Rows.Count.ToString();
 //strCountAll = dsHorses.Tables[0].Rows.Count.ToString();

 conn.Open();
CountStock = (int) cmd.ExecuteScalar();

 //cmd.CommandText = strSql;

// get full name for xtnd_code
// SqlDataAdapter adapter = new SqlDataAdapter(cmd.CommandText, conn);
// DataTable tblStyleNames = new DataTable("tblStyleNames");
// adapter.Fill(tblStyleNames);
// try
// {
// strStyleName = tblStyleNames.Rows[0] ["ListingTitle"].ToString();
// }
// catch
// {
// }

// END get full name for xtnd_code
 

 // count stock example direct query string required inside single quotes and allowing double quotes in array[ ] def
cmd.CommandText = "SELECT COUNT (img_num) "+
"FROM t_infimg "+
"WHERE xtnd_code = '" + Request.QueryString["PaintingCode"] + "' "+
"AND pubStatus = 'STOCK' AND isCutDown = '0' AND pubDisclude = '0' "+
"AND hasSQLImageOnline = 'VIEW' ";

//conn.Open();
//dlPaintings.DataSource = cmd.ExecuteReader();
//dlPaintings.DataBind();
//conn.Close();

 

Old Sql image embed code deprecated for thumbs

 <img src="../getImg.aspx?PaintingNumber=<%# DataBinder.Eval(Container.DataItem, "img_num") %>" align="top" border="1" height="80">

 //lblShape.Text = "<img src="+'"'+"frm_buyNowImg.aspx?PaintingNumber="+strPaintingID+'"'+
// " width="+'"'+"300"+'"'+" style="+'"'+"border: 1px solid #FF0000"+'"'+">";

 //lblShape.Text = "<img src="+'"'+"frm_buyNowImg.aspx?PaintingNumber="+strPaintingID+'"'+
// " height="+'"'+"300"+'"'+" style="+'"'+"border: 1px solid #FF0000"+'"'+">";

 

         

 

Meta-insights (You probably already know these, but a review can't hurt.)

C# ASP.NET controls have only very rudimentary function. Plus they only function within HTML sections and are not instantiated in code blocks. They only make calls to code blocks in the <script> area, and at best are databound to elements existing there.

Sql Server: Filtering based on given number of days prior today

> { fn NOW() } - 90

 

Escape Characters Microsoft Access
Escape Characters MS Access
Escape Characters VBA
Escape Ampersand VBA
Escaping Ampersand VBA
Escape Ampersand C# ASP.NET
Escaping Ampersand C# ASP.NET
Ampersand Escape Character VBA
Ampersand Escape Character MS Access
Escape & Microsoft Access
Escape & MS Access

Microsoft Access Visual Basic for Applications uses a doubling of the ampersand to escape it for use in Labels, etc. Such as

&&     in design view, gives you

&        in Report view



You'd think one could find this info easily at MSDN wouldn't you? Thank goodness for google.


Nonbreaking Space (non breaking space) C# ASP.NET (more)

 [C#]

\u00A0

Nonbreaking LineBreak (non breaking line break) C# ASP.NET (more)

 [C#]

\u000A
 

Ampersand C# ASP.NET (more)

 [C#]

\u0026
 

More Escape Sequences C# ASP.NET (more)

 [C#]

use such as: \u0022    (for double quote)
 

EscapeSequence:
\ b /* \u0008: backspace BS */
\ t /* \u0009:
horizontal tab HT */
\ n /* \u000a:
linefeed LF */
\ f /* \u000c:
form feed FF */
\ r /* \u000d:
carriage return CR */
\ " /* \u0022:
double quote " */
\ ' /* \u0027:
single quote ' */
\ \ /* \u005c:
backslash \ */
OctalEscape /* \u0000 to \u00ff: from octal value */

Changing normal.dot

File/Page Setup
 
Click the 'Default' button to be given opportunity to use the current document as the new 'normal.dot' in Microsoft Word.

Yes, I know. It makes no sense at all to have 'Default' refer to "changing" the default, but that's how it works.

Secret Code

 [C#]

<asp:TemplateColumn HeaderText="Photo">
<ItemTemplate>
<font face="Arial" size="1"><p align="right"
<b>
<a target="_top" href="getHorseAutoPhotoListing.aspx?RecHld=
                           <%# DataBinder.Eval(Container.DataItem, "HorseID") %>">
<img src="getHorsePhoto.aspx?HorseID=
                          <%# DataBinder.Eval(Container.DataItem, "RecHld") %>" border="1" height="55"
</a>
</b>
</font>
</ItemTemplate>
</asp:TemplateColumn>

Although there is an obvious and glaring error, this is what it took to both display a SQL Server image, then align it to the right. However, it doesn't matter how you say it: Storing images in SQL Server,  using SQL Server to store images, using SQL Server to display images, databinding images with ASP.NET and SQL Server, or browsing web enabled database images with ASP.NET and SQL Server, this little trick took a long fucking time to find, then futz into working order.

BTW: the mistake is that <p align="right" is not closed with an /p  tag, nor (as of 09/28/05) have I found any authority that would say the syntax is correct, but this is the only way I could get it to work??! Of course, none of this makes any sense whatsoever out of context, and without viewing the "getHorsePhoto.aspx" code behind, but the results can be viewed at:

http://www.equipoise.com/search/select/getHorseAuto.aspx

Endico Scan/Print Procedures

Pre-press scan and prep submittal process for print service providers - Endico haute conduite watercolors.

Web Enabled Database Test

04/27/05: updated "Page" directive in all non-forms aspx files to:

 <%@Page Language="c#" Debug="False" EnableSessionState="False" %>

per:  asp.netPRO Magazine May 2005, p.  19
re:    tuning performance by disabling the default Session State Manager where not needed

SQL Server:  Dynamic Bibliography (broken link)
Bibliography:   Click, Copy, Paste...  (source code) Link to:
Endico:  ListBox | get_files   (source code) Link to: Functioning Code

MDAC 2.8 download: Developers (not casual users), unless you update all your computers with this Microsoft download you are going to have immense trouble getting your data connections to work with any reliability.

Ports

Windows Server Port Requirements

Microsoft download site listing of default port usage in Excel spreadsheet format.

Unicode

http://www.unicode.org/

Legend

The following table indicates which modifiers are indicated by Icons found on the MSDN Library.

 public method
 static
 protected method
 public property
 protected property
 public event

C# Best Practices

UTF-8 encoding provides best portability for source text files

World's Simplest C# Program (aka: Simple C# Programming Guide)

Here is the world's simplest C# program.
 
[C#]

class Simplest
{
     static void Main()
     {
          System.Console.WriteLine("namespace.class.method");
     }
}

Just copy/paste the above text, beginning with the word 'class' to and including the final '}'  into a pure text file (using Notepad set the "Save as type:" to "All Files" and set "Encoding" to UTF-8), then save it with a name of your choosing to compile. Information about compiling from the command prompt is found in:

Liberty, Jesse. Learning C#. Cambridge: O'Reilly, 2002., pp. 8-9.

Be aware the figure '[C#]' above is not part of the program but merely points out that the language is C#. You will find this is a standard convention used to present code examples online.

Unfortunately a large number of published examples, such as the one that the above snippet was abstracted from, lead to confusion by including extraneous code in order to allow for expansion later in the text. The original Liberty example (p. 4), which the above code is based on, adds a namespace definition that is not required for the code to run. The code above has been simplified from the Liberty snippet to assure the true essence of C# stands out.

Another example of such misdirection can be found in:

Cooper, James W. C# Design Patterns: A Tutorial. Boston: Addison-Wesley, 2003., p. 17

Point number 2 states:

The program starts from a function called Main, and it must have exactly the following form.

static void Main(string[] args)

Of course my "World's Simplest C# Code" proves that 'string[] args' is not necessary, and also reveals the italics used for 'exactly' is an overstatement of misguidance.

If you are working your way through Liberty, be aware that there are numerous such errors and misdirections. For example, page 17 shows a use of the keyword 'private' which is not possible in the position shown. Also 'string' (a C# keyword) is capitalized by mistake. The VS.NET IDE catches the first mistake, while the second one is allowed inside the IDE but does not work if coded, compiled and run outside it.

In a French version of an O'Reilly book, I found a dubious procedure given as a coding example. It's  on page 4 of:

Drayton, Peter, Ben Albahari, and Ted Neward. C#: Précis & Concis. Trans. Yannick Aristidi. Paris: O'Reilly, 2002.

In any case the code example above is the simplest possible functional program that can be written using C# and the .NET Framework. Beginning with the line "class Simplest," each element is absolutely necessary for the code to run.

However, you can change two of the elements to suit your taste.

The word "Simplest" is just the name that I gave it. Plus it is capitalized only because that is a standard convention for words in that place. You might want to call it "tiny" or "Genius" or "pure," whatever pleases you. The words 'namespace.class.method' can also be anything you want—from "a" to 新年好 or anything in between, plus the dots (.) are not required. Using the string  'namespace.class.method' was done here to make the result of running the code somewhat instructive.

The instructive aspect is that the result that is written to your screen shows the keywords for the first two positions of the previous code statement with the name of the structural unit for the last position. That is to say 'System' is the namespace, 'Console' is the class, 'WriteLine' is the method. Be mindful that the statement 'System.Console.WriteLine' does in fact require the dots (.) plus the capitalization, but the characters within the double quotations ("namespace.class.method") can be any.

For more about defining the basic C# language constituents see: C# Morphology.
 

NOT PSEUDO-CODE

Below are two snippets of code that appeared to be pseudo-code on first glance, but in fact (taken together) they compile, run perfectly, and provide incredible insight into the inner workings of C#.

Copy/Paste,  Save and Compile both snippets using the simple directions following them.

[C#]

using System;

namespace Acme.Collections
{
     public class Stack
     {
          Entry top;
          public void Push(object data) {
               top = new Entry(top, data);
          }
          public object Pop() {
          if (top == null) throw new InvalidOperationException();
          object result = top.data;
          top = top.next;
          return result;
          }
          class Entry {
               public Entry next;
               public object data;
               public Entry(Entry next, object data) {
                    this.next = next;
                    this.data = data;
               }
          }

     }

}

 

[C#]

using System;
using Acme.Collections;

class Test
{
     static void Main() {
          Stack s = new Stack();
          s.Push(1);
          s.Push(10);
          s.Push(100);
          Console.WriteLine(s.Pop());
          Console.WriteLine(s.Pop());
          Console.WriteLine(s.Pop());
     }
}

Copy paste the text beginning with the  "using System;" line into a Notepad document, then save as a plain text file.  Name the first snippet "acme.cs" and compile it thus:

csc /t:library acme.cs

Name the second snippet "test.cs" and compile it thus:

csc /r:acme.dll test.cs

You do not even need to type the csc commands. Highlight and copy each from this page, then right click your DOS compiler's top border and choose "Edit/Paste."

The first snippet will be compiled to "acme.dll" while the second will be compiled to "test.exe" which may be run from the command line.

This example comes from:

Hejlsberg, Anders, Scott Wiltamuth, and Peter Golde. "The C# Programming Language". Boston: Addison-Wesley, 2004. ISBN: 0-321-15491-6 (pp. 5-6)

Buy the book.

Online this book exists as an English Version, a French Version, a German Version, an Italian Version, and a Spanish Version among others (probably), but much of the helpful elaboration found in the hardcopy English version of the book is missing.

For leads to more languages see MSDN Worldwide.

I wish the Hejlsberg book had been available when I started studying C#. It would have saved me a lot of effort when putting together my C# Morphology.

 

Displaying Microsoft SQL Server Images with C# and ASP.NET

Here it is, clear and simple. See the Online links below. You will have to know a little bit about C#.

Then you can just copy paste the code samples into NotePad, save each page as a text file with the suggested names into any web folder, set up a SQL table as indicated, alter your NotePad copies of the code's SQL connection strings to match your own server address, user id (user name), password, and the name of your database where you put the new table. Afterwards open the aspx pages in your browser. The code works.

Please use online version.

Online: | Part 1 | Part 2 - | page 1 | page 2 |

If unavailable, this archive version has been maintained in case online resource disappears.

Archived: | Part 1 | Part 2:  | page 1 | page 2 |

The only thing I don't like about the superdotnet.com site, where these articles come from, is the anonymity of the writers. I can deal with the flashing pop-ups and banners, since the quality of information is so high, but I would like to know who (not what) to credit.

However, this bit of information about viewing images in a SQL Server database is certainly worth the trouble and also seems to be something that should be addressed in every book about the subject of C#, ASP.NET, and web enabled databases. It isn't.

Here is a link to a database that works the way it should. It has simple controls and fast returns from 4341 files. Unfortunately it is not done with SQL Server but with FileMakerPro, or so I gather from the URLs that always mention "FMPro": Botanical Image Database, University of Basel.

Circular Logic Oddity

In C# a class may sometimes call itself, from within itself with no ill effects.

This next snippet of code points out an illogical aspect of C# programming. This code runs without incident, but the logic implies an infinite loop could result.

 
[C#]

using System;
namespace StaticTester
{
     class Tester
     {
          public void Run()
          {
               Console.WriteLine("Hellow World!");
          }
           static void Main()
           {
                Tester t = new Tester();
                t.Run();
           }
      }
}

From inside the class Tester, Main() instantiates a new instance of class Tester which would logically also call its own instance of Main() which in turn would instantiate a new Tester(), again, again, and again. However, this does not happen. The code runs, and C# has taken care of another problem for you.

The snippet above was simplified by removing the comment lines from an example in:

Liberty, Jesse. Learning C#. Cambridge: O'Reilly, 2002., pp. 105-6.

Time Stamp C# ASP.NET

11/01/11

PROBLEM: Once again the illusive Time Stamp has experienced a change while most of the top level search engine returns reveal such statements as, "Why would you want to do that? Pages are dynamic." However, a clearly dated and time stamped page helps searchers avoid wasting time on information that is outdated and while otherwise confirming that something found is useful though historic and timeless... which is the case for the Endico Signature Specimens page.

SOLUTION: Massive amount of time tracking down this simple line of code:

string strLastModified = System.IO.File.GetLastWriteTime(Server.MapPath("myPageName")).ToString("MM/dd/yyyy H:mm:ss")

Which in the world of KeyTap® script block worked out to:

// timestamp
lblTimeStampDate.Text = System.IO.File.GetLastWriteTime(Server.MapPath("/sig/index.aspx")).ToString("MM/dd/yyyy");
lblTimeStampTime.Text = System.IO.File.GetLastWriteTime(Server.MapPath("/sig/index.aspx")).ToString("HH:mm:ss tt");

and in the html block

 <blockquote><font face="Georgia" size="1">
          <i>
this page last updated:</i>&nbsp;&nbsp;&nbsp;<asp:Label ID="lblTimeStampDate" Runat=server />
                                                                          &nbsp;&nbsp;<asp:Label
ID="lblTimeStampTime" Runat=server />
                                                                         <p>&nbsp;</p></font>
</blockquote>

which looks like this on the rendered page

this page last updated:   11/02/2011   10:38:49 AM

to match server to local time (server in California, editing in NY) simply add AddHours(3) thus

lblTimeStampTime.Text = System.IO.File.GetLastWriteTime(Server.MapPath("/sig/index.aspx")).AddHours(3).ToString("HH:mm:ss tt");

Formatting specifics are found on the Microsoft web site at:  date/time format specifiers.

Of course, syntax for select Sql Server to add hours to timestamp differs (for such as Chatterbox)

SELECT DATEADD(hh, 3, Timestamp) AS Timestamp;

Where 'Timestamp' is the name of a Sql Server date/time
and 'hh' specifies hours

See more at: Sql Server date/time format specifiers, and elsewhere.

Plus, syntax for MySql requires (for such as Chatterbox)

DATE_ADD(myDataField, INTERVAL +3 HOUR) AS Timestamp

with the following in DataList HTML

<%# DataBinder.Eval(Container.DataItem,"Timestamp") %>

assuming "myDataField" is a true MySql DateTime field in the format

1992-01-01 00:00:00

There you go, nothin' to it, and it only took a week to figure out because the utility software

Sobolsoft - MS Access MySQL Import, Export & Convert Software

doesn't convert MS Access DateTime to MySql DateTime (text field results only)

So it only took another 1.5 days full time to find correct converters to get this finally right

Otherwise

Years ago, the article found next on this page about time stamping gained long standing stature in search engines, so it is best to leave it below as was despite the fact that using it causes a change in date/time on each load, so here it is:


(the original post)

06/27/03: VS .NET does not provide a simple TimeStamp in the manner of FrontPage, a Google search found a snippet of code on the Visual Studio Magazine Site that did the trick. However the VS.NET IDE makes using this code a complex issue. So...

10/05/03: A better solution to the Time Stamp problem was found in "Beginning ASP.NET with C#," Goode et al., p. 50, but an even more trivial answer was derived by simply trying a variation on the code sample given in the book. Here's my variation:
 
[C#]

time.Text = DateTime.Now.ToString();

<asp:label id="time" runat="server"/>

[ Note: see better above ]

Place the first line in your C# <script> block and the second line anywhere in your html that you wish the time stamp to appear.

Note: The "[C#]" comment is merely a convention to indicate the programming language used. It is not part of the code.

BTW: If you want more than one Time Stamp on a page, you must copy both lines with a new id, such as "time2.Text" for the first line and "label id=time2" for the second.

See also HOWTO: Prevent Caching in Internet Explorer, a microsoft.com article that addresses keeping pages current, or you may View/Source on this page and check out the headers .
 


VS.NET

Logical placement of created files for New Projects:

1) in IIS MMC create virtual directory using proposed project name (e.g., myName)

2) create project (myName) in VS allowing localhost location

3) myName.sln & myName.sou files will be automatically placed in new browsable localhost folder (myName) while remaining VS files will be placed in physical location of your pre-named (myName) virtual directory

In addition to the *.sln and *.sou files mentioned in item 3 above that are placed in the browsable localhost root directory, for New Projects VS creates and automatically places default files in the physical location of your named (myName) virtual directory. These files are:

[bin] (empty folder)
AssemblyInfo.cs
Global.asax
Global.asax.cs
Global.asax.resx
Web.config
WebForm1.aspx
WebForm1.aspx.cs
WebForm1.aspx.resx
myName.csproj
myName.csproj.webinfo
myName.vsdisco

However, only the following files are viewed in Solution Explorer from within VS:

AssemblyInfo.cs
Global.asax
Web.config
WebForm1.aspx
WhatIsWhere4.vsdisco

the remaining *.cs files are available through context sensitive clicking "View Code" links such as "WebForm1.aspx.cs" displays when clicking "View Code" (F7) while focus is on WebForm1.aspx.
 

ASP.NET

For coding aspx (web pages) 'Page_Load()' is essentially equivalent in usage to the code blocks with ID 'Main()' used in Console and Windows Applications. The server will begin with the "Page_Load()" code block, and if the ID (Page_Load) is misspelled the C# code will be broken—even though the remaining html will display normally.

Pages 39 & 55 of Goode et al. 2003 shows folder permissions set to: "Scripts and Executables" when, in fact, "Scripts Only" is all that is necessary. Furthermore, if set as shown, Front Page will refuse to allow publication of files stating "/" is and executable directory and downloading files is not permitted.

Per Goode et al. 2003 p. 29: using "127.0.0.1" is synonymous with "localhost" in the context of "http://localhost/";  but, oddly, on my computer "127.0.01" and "127.001" functions in the same way. Otherwise, "127001" is refused as would be expected.

DOS rename  and replace file name characters

REN %%I !FILE:~0,1!!FILE:~10,3!!FILE:~14,1!%%~xI

http://www.computing.net/answers/dos/renaming-characters-in-a-file-name-/11809.html
or local N:\Software\DOS\

Files Downloaded for Academic Archive

Natural vs. Programming Languages

Chat re: Port 80 blocked (chat file found re: Optimum blocking Port 80)

06/09/03: After much confusion regarding inability to serve web pages from home, found the chat room thread linked above using Google search: "optimum online" "blocking port 80"; reassigned links and server to Port 9003 per IAIA statement that 9003 is "Unassigned."

For assistance checking connectivity and working through the Port 80 problem thanks to: Katherine Doob, Ian Duke, Katherine Endico, Rob Fichter, John Mitchell.

Time Stamp C#: Visual Studio Magazine article (find code at "see Listing 1")

Reading Notes††

Kennedy, 1998

Archival Copy of early KeyTap®

Following are links outlining early KeyTap, and my involvement in the Sugar Loaf Community.

First is a description of Sugar Loaf circa 1996 that is abstracted from the KeyTap web site. Second is a pdf copy of the document that offered free membership to the Sugar Loaf Guild in June of 1997. This document describes benefits and services, offered at no charge, for artisans living and working in the hamlet. Third is a link to the full early KeyTap site with its sub-links to other aggregations such as the sites of members of the Artisan's of Sugar Loaf that resulted from the KeyTap offer.

Brief History of Sugar Loaf Guild

This link opens a brief description of Sugar Loaf village of Artisans at the time the invitation to join the Sugar Loaf Guild (see link below) was presented to the various organizations within the community.

[pdf] Invitation to Sugar Loaf Guild Membership (June 1997/92 kb)

This is a PDF copy of the original document that offered free membership and outlined the benefits of joining the Sugar Loaf Guild.

Unfortunately the Internet plus electronic tracking/communications in general were new concepts and not well understood, so a standard response was, "Ok...but what's in it for us?" Yes, I was as shocked as you.

Despite the lack of understanding I kept the offer open, in conjunction with the Artisans of Sugar Loaf (a committee of the Sugar Loaf Foundation), for the next four years hoping enough people would come online to see what this computer stuff was all about. They may get here someday yet.

For a time KeyTap also hosted gratis the official web site for the Town of Chester, NY. That site never achieved actual content due to an aggressive proactive stance on the part of the Town Board and other local government agencies to "hide all information possible from the public." But that is another story and one I didn't quite understand at the time, even though I served eight years on the Planning Board. Here's the brief.

One person who was supposed to be one of my liaisons was subsequently convicted of embezzlement, plus another was removed from their position by the Department of Environmental Conservation. Those events define the tip of a very deep iceberg which was itself not even slightly thawed by the heat directed on it. I personally considered my last official duty as Planning Board member to be the 2 hours and 45 minutes spent in a private meeting with an FBI agent, handing over a wealth of information I gathered and begging for something to be done. Those events gave me a refined sense of how it comes about that some people may find it necessary to fly big jets into tall buildings. I absolutely do not condone such action, but I sure do understand it.

KeyTap® Early Years

When following this link, be aware that a unique use of straight HTML, plus a clever use of directory naming conventions extended from DNS functions available at the time (1996), combined in a way that allowed each site of the Sugar Loaf Guild Members and Ar