cSharpeningDotNet

Microsoft C# (c sharp) goodies, yum yum!

Also see my Web App blog

Simple loop thru resultset

        public static List<Object> GetFirstColumnAsArray(string sql, string connString) {
            List<Object> listOfDataFromFirstColumn = new List<object>();
            UtilsDatabase db = new UtilsDatabase(connString);          
            OracleDataReader rs= db.getResultSetFromSelectSQL(sql);
            while(rs.Read()) listOfDataFromFirstColumn.Add(rs[0]);
            db.closeConnection();
            return listOfDataFromFirstColumn;
        }


Simple fun dos menu technique


        static void Main(string[] args) {

            Boolean done = false;

            while(!done) {

                Console.WriteLine("********************************************");

                Console.WriteLine("** Select an option below and press enter **");
                Console.WriteLine("********************************************");
                Console.WriteLine("  1)  Run Generic Chart Test1");
                Console.WriteLine("  2)  Run DB Chart Test1");
                Console.WriteLine("  Q)  Quit");
                Console.WriteLine("********************************************");
                String userSelectedOption = Console.ReadLine();
                switch(userSelectedOption) {
                    case "1": Test_Functions.TestChartUtils_WithDbData(); done = true; break;
                    case "2": Test_Functions.TestStringXaxis(); done = true; break;
                    case "Q":
                    case "q": done = true; break;
                    default: Console.WriteLine("Invalid selection."+Environment.NewLine); break;
                }
            }
        }

Super Simple BackgroundWorker (not in main/UI thread)


using System;

using System.ComponentModel;

using SharedLib;

namespace BackgroundWorkerTest {

    /// <summary>

    /// Simple BackgroundWorker which takes a parm, <para/>
    /// Reports Progress (via int and informative string) <para/>
    /// Returns an informative string result <para/>
    /// needs     using System.ComponentModel;  for backgroundWorker
    /// </summary>
    class Program {
        static void Main(string[] args) {
            BackgroundWorker backgroundWorker=new BackgroundWorker();
            //backgroundWorker.CancelAsync();
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;
            backgroundWorker.DoWork += new DoWorkEventHandler(DoBackgroundWork);
            backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
            backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
            backgroundWorker.RunWorkerAsync("file1.csv");
            UtilsClass.WaitSeconds(15);
        }
        /// <summary>
        /// Inform user of background worker progress
        /// <para/> This runs on main ui thread
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
            int backgroundWorkerProgess = e.ProgressPercentage;
            String backgroundWorkerStatusString = e.UserState as String;
            logIt(backgroundWorkerStatusString + " Progress: " + backgroundWorkerProgess);
        }
        /// <summary>
        /// Handle the worker's  e.Result  (and/or user cancellations or errors)
        /// <para/> This runs on main ui thread
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
            if(e.Error != null) {   // handle the error
            } else if(e.Cancelled) { // handle cancellation
            } else {
                logIt("Results "+(String)e.Result);
            }
        }
        /// <summary>
        /// Simple background job runs 10 loop iterations with 1 second timer in each
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void DoBackgroundWork(object sender, DoWorkEventArgs e) {
            BackgroundWorker backgroundWorker = sender as BackgroundWorker;
            String fileName = (String)e.Argument;   //parm passed in
            int cnt=0; int cntMax= 10;
            while(cnt<cntMax) {cnt++;
                UtilsClass.WaitSeconds(1);
                if((backgroundWorker.CancellationPending == true)) {
                    e.Cancel = true; break;
                } else {
                    backgroundWorker.ReportProgress(cnt, fileName);
                }
            }
            e.Result = fileName+ " finished at " + DateTime.Now; //result given back to main thread (via worker_Completed)
        }//DoBackgroundWork

        static void logIt(String msg) {UtilsClass.LogToVisualStudioOutputWindow(msg);}
    }//class
}//ns


Project Properties

Visual Studio projects generally have a folder called "Properties" with a text file called Settings.settings and c# program called Settings.Designer.cs

If you manually add a property (name/value pair), then make sure you update both files above.


To always get the app root path for asp server controls use the tilde like below:

<asp:Image ID="MyImg" ImageUrl="~/_assets/mailhover.gif" runat="server" />


Get app root path for NON server html elements

Some HTML elements do NOT have a corresponding asp.net server control object.
 so even if you add:  runat=”server” to a standard html element, the “~” (Tilde) will not work. 

 these elements get converted as HtmlGenericControls at the server-end, 

   which can resolve the Tilde(~) operator to a path

So for these html-only elements, use Page.ResolveClientUrl()

 For example:  

  <link href='<%=ResolveClientUrl("~/mystyles/style1.css")%>' type="text/css" rel="Stylesheet" />

Find the matching brace in visual studio (the end of the loop/branch)

visual studio w/cursor before or after the opening brace 

  press CTRL + ]

Text colors in visual studio


c# .net programming in visual studio is nicer with colored source code text

For example, you can change comment colors for method comments
 which is nice when scrolling through large source code


Update a DataTable Row/Column

        /// <summary>
        /// Output looks like this:
        /// table contents:
        /// C1:r1c1 C2:r1c2
        /// updating table
        /// table contents:
        /// C1:r1c1 C2:updated!
        /// </summary>
        static void testDataTable() {
            DataTable dTbl = new DataTable();
            dTbl.Columns.Add("C1");
            dTbl.Columns.Add("C2");
            DataRow dRow =dTbl.NewRow();
            dRow["C1"] = "r1c1";
            dRow["C2"] = "r1c2";
            dTbl.Rows.Add(dRow);
            Console.WriteLine("table contents:");
            foreach(DataRow row in dTbl.Rows) {
                Console.WriteLine("C1:" + row["C1"] + " C2:" + row["C2"]);
            }
            Console.WriteLine("updating table");
            DataRow[] rows = dTbl.Select("C1='r1c1'");
            rows[0]["C2"] = "updated!";
            Console.WriteLine("table contents:");
            foreach(DataRow row in dTbl.Rows) {
                Console.WriteLine("C1:" + row["C1"] + " C2:" + row["C2"]);
            }
        }


Notes about List vs ArrayList (which is like Java Vectors)

Use List<T> instead of ArrayList's since .NET 2.0

 because List<> is aware of generics

List<T> examples:

using System.Collections.Generic;
        /// <summary>
        /// simple bean with id and desc
        /// create list of beans
        /// find bean by id or desc
        /// </summary>
        static void testFindOfListOfBean() {
            List<Beany> beanyList=new List<Beany>();
            beanyList.Add(new Beany("APPLE", "FRUIT"));
            beanyList.Add(new Beany("CARROT", "VEGGIE"));
            string beanyIdToFind = "CARROT";
            Beany beanyFound = beanyList.Find(item => item.id.Equals(beanyIdToFind)); 
            if(beanyFound == null) throw new NullReferenceException("Error in testFindOfListOfBean: beany NOT found with ID:" + beanyIdToFind);
            Console.WriteLine("Id of beany found:" + beanyFound.desc);

            beanyIdToFind = "DONTEXIST";
            beanyFound = beanyList.Find(item => item.id.Equals(beanyIdToFind)); // Finds first element greater than 20
            if(beanyFound == null) throw new NullReferenceException("Error in testFindOfListOfBean: beany NOT found with ID:" + beanyIdToFind);
            Console.WriteLine("Id of beany found:"+beanyFound.desc);
        }

    public class Beany {
        public string id, desc;
        public Beany(string idParm, string descParm){
            id=idParm;
            desc=descParm;
        }
    }
=============================================================
This static bean self-tracker worked also:

        /// <summary>
        /// simple bean with helpful method to track other bean instantiations  <para/>
        /// steps: <para/>
        /// create beany1 (it will store itself in its own STATIC list)
        /// create beany2 (it will store itself in its own STATIC list)
        /// list all beany's in the STATIC list
        /// </summary>
        static void testBeanyStaticListSelfTracker() {
            Beany b1 = new Beany("APPLE", "FRUIT");
            Beany b2 = new Beany("CARROT", "VEGGIE");
            foreach(Beany beany in Beany.StaticList) {//list all beanies!
                Console.WriteLine("Id of beany found:" + beany.desc);
            }
        }

    /// <summary>
    /// Has static List to store list of currently instantiated beanies
    /// </summary>
    public class Beany {
        public string id, desc;
        public Beany(string idParm, string descParm){
            id=idParm;
            desc=descParm;
            StaticList.Add(this);
        }
        public static List<Beany> StaticList = new List<Beany>();
    }



GridView Goodies

Dynamically assign a row bound function

Note: this MUST occur BEFORE the data is bound!

   protected void Page_Load(object sender, EventArgs e) {
        GridView grid=new GridView();
        grid.DataSource = dTbl;
        grid.RowDataBound += new GridViewRowEventHandler(gridRowDataBound);
        grid.DataBind();
   }
   void gridRowDataBound(object sender, GridViewRowEventArgs e){
        foreach(TableCell cell in e.Row.Cells)   cell.Text = HttpUtility.HtmlDecode(cell.Text);

   }

Change colors of header and detail grid rows
  void gridView_RowDataBound(object sender, GridViewRowEventArgs e) {
            
            UtilsWebGridView.grid_RowDataBoundHelper(sender, e);
            if(e.Row.RowType==DataControlRowType.Header) {
               e.Row.BackColor=System.Drawing.Color.Gray;
            }else{
                  foreach (DataControlFieldCell Cell in e.Row.Cells){
                       Cell.BackColor= System.Drawing.Color.Blue;
                  }
            }
}

Hide columns via RowDataBound

        void gridView_RowDataBound(object sender, GridViewRowEventArgs e) {
            if(e.Row.RowType == DataControlRowType.Header) {
                e.Row.Cells[ColumnIndex_MeasureId].Visible = false; //hide measure_id header cell
                foreach(DataControlFieldCell cell in e.Row.Cells) {
                    if(cell.Text == "OPER"
                    || cell.Text == "GREEN"
                    || cell.Text == "YELLOW")
                       cell.CssClass = "tiny";
                }
            } else {//detail row
                e.Row.Cells[ColumnIndex_MeasureId].Visible = false; //hide measure_id detail cells

                //Clean up Operator ...replace GT with >=

DataTable Goodies

Find column index (based on column name)
        public static int getDataTableColumnIndex(DataTable dtaTbl, string colName){
            DataRow dtaRow =dtaTbl.Rows[0];
            DataColumn dtaCol= dtaRow.Table.Columns[colName];
            if (dtaCol != null){
                int idx=dtaCol.Ordinal;
                return idx;
            }
            throw new Exception(string.Format("Column '{0}' not found in table", colName));
        }

Dynamically add components to aspx web page div


using System;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;



namespace WebAppTest {

    public partial class WebForm1 : System.Web.UI.Page {

        static string btn1 = "btn1", btn2 = "btn2";

        protected void Page_Load(object sender, EventArgs e) {



            Button button= new Button();

            button.ID = btn1; button.Text = btn1;

            button.Click += new EventHandler(button_Click);

            DIV1.Controls.Add(button);

            DIV1.Controls.Add(new LiteralControl("<hr/>"));



            button = new Button();

            button.ID = btn2; button.Text = btn2;

            button.Click += new EventHandler(button_Click);

            DIV1.Controls.Add(button);

            DIV1.Controls.Add(new LiteralControl("<hr/>"));

        }

        private void button_Click(object sender, EventArgs e) {

            Button b = (Button)sender;

            b.Text = "you clicked:" + b.Text;

        }

    }

}

------------------------------------------
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebAppTest.WebForm1" %>
<!DOCTYPE html>
<body>
    <form id="form1" runat="server">
        <div id="DIV1" runat="server"></div>
    </form>
</body></html>

Or dynamically add a div to the page
using System;
using System.Web;
using System.Web.UI;
using SharedLib; //has oracle functions in it from the managed driver
//using Oracle.ManagedDataAccess.Client;
namespace WebAppTest {
    public partial class GridPages : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            
            UtilsWeb.LoadGridFromDb(GRID_PAGE_TEST,
                UtilsDatabase.ConnectionString_SERV1,
                UtilsDatabase.OraManagedProviderName,
                "select * from dual" //sql
                );

            string dt = UtilsClass.GetNowYYYYMMDD(), sql = "insert into temptest values('" + dt + "')";
            UtilsDatabase db = new UtilsDatabase(UtilsDatabase.ConnectionString_SERV1);
            UtilsClass.LogToVisualStudioOutputWindow("inserting");
            string result=db.runInsertStatement(sql);
            UtilsClass.LogToVisualStudioOutputWindow("inserted. "+result);
            db.closeConnection();

            System.Web.UI.HtmlControls.HtmlGenericControl createDiv = new
            System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
            createDiv.ID = "createDiv";
            createDiv.InnerHtml = sql+" "+result;
            this.Controls.Add(createDiv);
        }
    }
}


Get current path name (does NOT have the backslash \ at the end) 

Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\";


You can use . for current uri, or .. for parent:

Response.Redirect("../F01/S006.aspx"); 



The "USING" keyword/clause/command/feature:

For Streams, "USING" auto flushes, closes & calls IDisposable.Dispose on the stream!



File IO


Read a file

class ReadFromFile{
    static void Main(){
        //Read file as a single string.
        string text = System.IO.File.ReadAllText(@"C:\Users\Public\dir1\WriteString.txt");
        System.Console.WriteLine("Contents of WriteText.txt = {0}", text);

        //Read file into string array. 
        string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Public\dir1\WriteLines2.txt");
        System.Console.WriteLine("Contents of WriteLines2.txt = ");
        foreach (string line in lines){
            Console.WriteLine("\t" + line); //tab + line
        }
        Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}

Write a File

class WriteTextFile{
        //Assumes "C:\Users\Public\dir1" folder exists
        //Note: "USING" auto flushes, closes & calls IDisposable.Dispose on the stream!
    static void Main(){
        //WriteAllText: creates file, writes string, closes file 
        string text = "A class is the most powerful data type in C#. Like a structure, " +
                       "a class defines the data and behavior of the data type. ";
        System.IO.File.WriteAllText(@"C:\Users\Public\dir1\WriteText.txt", text);

        //WriteAllLines: creates file, writes ENTIRE array, closes file
        string[] lines = { "First line", "Second line", "Third line" };
        System.IO.File.WriteAllLines(@"C:\Users\Public\dir1\WriteLines.txt", lines);

        //StreamWriter encodes selected array strings as text (whereas FileStream writes bytes)
        using(System.IO.StreamWriter file = 
            new System.IO.StreamWriter(@"C:\Users\Public\dir1\WriteLines2.txt"))        {
            foreach (string line in lines)            {
                if (!line.Contains("Second")) file.WriteLine(line);
            }
        }
        //Append text to existing file
        using(System.IO.StreamWriter file = 
            new System.IO.StreamWriter(@"C:\Users\Public\dir1\WriteLines2.txt", true)){
            file.WriteLine("Fourth line");
        }
    }

A more complete example:
using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.Diagnostics;
namespace TestFileOps {
    //Note: "USING" auto flushes, closes & calls IDisposable.Dispose on the stream!
    //Uses System.Reflection; and System.Diagnostics;
    class Program {
        public static string NewLine = Environment.NewLine;
        static void Main(string[] args){
            string fileName="temp1.txt";

            //WriteStringToFile("line1", null,fileName);
            string[] tempArray = { "l1", "l2" };
            WriteArrayToFile(tempArray,null, fileName);
            AppendTextToFile("line2", null, fileName);

            string[] lines = ReadFileIntoArray(null, fileName);
            foreach(string line in lines) {
                Console.WriteLine(line); 
            }
            string textFromFile = ReadFileIntoString(null, fileName);
            System.Console.WriteLine(textFromFile);
            
            Console.WriteLine("Press any key to exit."); //user prompt/wait
            System.Console.ReadKey();
             
        }
        /// <summary>
        /// Read file into string array. 
        /// this will auto escape the path
        /// please include the slash at the end
        /// if path is null, it assumed the current dir 
        /// </summary>
        /// <param name="filePath">c:\myDir\</param>
        /// <param name="fileName">myfile.txt</param>
        public static string[] ReadFileIntoArray(string filePath, string fileName) {
            Console.WriteLine(GetMethodName()+" parms: "+filePath+fileName);
            return System.IO.File.ReadAllLines(@GetCleanPathString(filePath) + fileName);
        }
        /// <summary>
        /// Read file as a single string.
        /// this will auto escape the path
        /// please include the slash at the end
        /// if path is null, it assumed the current dir 
        /// </summary>
        /// <param name="filePath">c:\myDir\</param>
        /// <param name="fileName">myfile.txt</param>
        public static string ReadFileIntoString(string filePath, string fileName) {
            Console.WriteLine(GetMethodName()+" parms: "+filePath+fileName);
            return System.IO.File.ReadAllText(@GetCleanPathString(filePath) + fileName);
        }
        /// <summary>
        ///  WriteAllText: creates file, writes string, closes file. 
        ///  It auto adds an Environment.NewLine at the end.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="filePath"></param>
        /// <param name="fileName"></param>
        public static void WriteStringToFile(string text, string filePath, string fileName) {
            Console.WriteLine(GetMethodName()+" parms: "+filePath+fileName);
            System.IO.File.WriteAllText(@GetCleanPathString(filePath) + fileName, text+NewLine);
        }
        /// <summary>
        /// WriteAllLines: creates file, writes ENTIRE array, closes file
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="filePath"></param>
        /// <param name="fileName"></param>
        public static void WriteArrayToFile(string[] lines, string filePath, string fileName) {
            Console.WriteLine(GetMethodName()+" parms: "+filePath+fileName);
            System.IO.File.WriteAllLines(@GetCleanPathString(filePath) + fileName, lines);
        }
        /// <summary>
        ///  StreamWriter encodes selected array strings as text (whereas FileStream writes bytes)
        ///  It auto adds an Environment.NewLine at the end.
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="filterText"></param>
        /// <param name="filePath"></param>
        /// <param name="fileName"></param>
        public static void WriteSelectedArrayStringsToFile(string[] lines, string filterText, string filePath, string fileName) {
            Console.WriteLine(GetMethodName()+" parms: "+filePath+fileName);
            using(System.IO.StreamWriter file =
                new System.IO.StreamWriter(@GetCleanPathString(filePath) + fileName)) {
                foreach(string line in lines) {
                    if(line.Contains(filterText)) file.WriteLine(line+NewLine);
                }
            }
        }
        /// <summary>
        /// Append text to existing file
        /// It auto adds an Environment.NewLine at the end.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="filePath"></param>
        /// <param name="fileName"></param>
        public static void AppendTextToFile(string text, string filePath, string fileName) {
            Console.WriteLine(GetMethodName()+" parms: "+filePath+fileName);
            using(System.IO.StreamWriter file =
                new System.IO.StreamWriter(@GetCleanPathString(filePath) + fileName, true)) {
                file.WriteLine(text+NewLine);
            }
        }
        /// <summary>
        /// this adds the trailing backslash\
        /// </summary>
        /// <returns></returns>
        public static string GetCleanPathString(string filePath) {
            if(filePath==null) filePath=Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            if(!filePath.EndsWith("\\")) filePath = filePath + "\\";
            return filePath;
        }
        public static string GetMethodName() {
            return new StackTrace().GetFrame(1).GetMethod().Name;
        }
    }    
}



AT symbol @

The "at symbol" @ allows using reserved keyword as a variable:
int @int = 15;
it also eliminates the neet to escape characters with '\':
var var1 = @"c:\myPics\pic1.png"
instead of
var var1 = "c:\\myPics\\pic1.png"


Simple console app with GUI added


using System;

using System.Windows.Forms; //else Application doesn't exist in the current context.



namespace ConsoleGuiPopupTest {

    class Program {

        static void Main(string[] args) {

            Application.Run(new WinForm1());

        }

    }

}


I had to make the label Modifier "Public"
 so I could set the label text in the C# code

I also had to set the label's auto-size=false,
   ...so I could manually size it


Show GUI and cmdline help if user double-click's your exe

using System;
using SharedLib;
using System.Windows.Forms; //for GUI and "Application" references 
namespace com.InfoDoc {
    /**
     *  .csproj file specifies a hintPath pointing to the location of dependant dll's
         It is recommended the caller uses relative paths such as:
        <ItemGroup>
          <Reference Include="Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=MSIL">
             <SpecificVersion>False</SpecificVersion>
             <HintPath>.\Oracle.ManagedDataAccess.dll</HintPath>
          </Reference>
          <Reference Include="SharedLib, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
             <SpecificVersion>False</SpecificVersion>
             <HintPath>.\SharedLib.dll</HintPath>
          </Reference>
      ...
  */
    class MainProgram {
        static string cr = Environment.NewLine;
        static string helpInfo=" ******************************************************************************************************"+cr
            +" Requestor.....: Bob."+cr
            +" Developer.....: Michael Dockery"+cr
            +" Created.......: 22-Mar-2016"+cr
            +" Dependencies..: "+cr
            +"               Oracles managed driver Oracle.ManagedDataAccess.dll"+cr
            + "               Our own custom utils SharedLib.dll" + cr
            + "               .NET version 4.  FYI: The Current version installed on this system is " + Environment.Version.ToString() + cr
            +" ******************************************************************************************************"+cr
            +" Purpose.......: "+cr
            +"     This program processes blablabla "+cr
            +"  "+cr
            +" Usage........: "+cr
            +" This application should be run from a script or from the commandline. "+cr
            +" ******************************************************************************************************" + cr;

        static void Main(string[] args) {
            if(args.Length == 0) {//user doubleclicked exe file, just show help gui (do NOT run main logic)
                Console.WriteLine(helpInfo); //show help on cmdline
                HelpForm helpForm = new HelpForm();
                helpForm.HelpLabel.Text = helpInfo; //set label modifier to Public and autosize=false
                Application.Run(helpForm);
                return;
            } else if(args[0].ToUpper().Contains("HELP")) {
                Console.WriteLine(helpInfo); //help requested via cmdline
            } else {//just run the app
                Console.WriteLine("Main is running..."); //help requested via cmdline
...
                Console.WriteLine("Main completed."); //help requested via cmdline
            }
        }
    }

}

# comments (the xml comments the developer puts on functions/methods)

 to show up in another project from a dll in visual studio:
 1) ensure compiler emits XML doc comments as part of the compilation job (for via /doc commandline switch)
 2) XML filename should match DLL filename (aka: myfile.dll -> myfile.xml)

 3) ensure the XML file is in same dir as DLL being referenced in some other project

/// <exception cref="System.Exception">Thrown when...</exception>

Simple c# app which reads from db



using System;
//using System.Data.OracleClient is depricated.
//using Oracle.DataAccess.Client; is a deployment nightmare ...has too many dlls

using Oracle.ManagedDataAccess.Client; //requires .net4, but is great for deployment cuz only needs 1 DLL!!!!!
//solution -> project -> references ->
//C:\app\ODAC_12c4_client32bit\mdockery\product\12.1.0\client_1\odp.net\managed\common\Oracle.ManagedDataAccess.dll
//ODAC was downloaded/installed from http://www.oracle.com/technetwork/topics/dotnet/index-085163.html



Use properties file for db connection:

namespace DbApp {
    class Program {
        static void Main(string[] args) {
            string connStr=DbApp.Properties.Settings.Default.ConnectionString;
            Console.WriteLine("Creating conn...");
            OracleConnection conn=new OracleConnection();
            try{Console.WriteLine(connStr);          
                conn.ConnectionString = connStr;
                Console.WriteLine("Opening conn...");
                conn.Open();
                Console.WriteLine("Conn state:"+conn.State);
                Console.WriteLine("Creating conn stmt...");
                OracleCommand command=new OracleCommand("SELECT * FROM dual",conn);
                Console.WriteLine("running stmt...");
                OracleDataReader dataReader=command.ExecuteReader();
                Console.WriteLine("reading results...");
                if(dataReader.Read()) Console.WriteLine(dataReader.GetName(0)+"="+dataReader[0].ToString());              
            } catch(OracleException ex) {
                Console.WriteLine("Ora Exception Code: " + ex.ErrorCode + " number:" + ex.Number);
                Console.WriteLine("Ora Exception Message: " + ex.Message);
                Console.WriteLine("Ora Exception Source: " + ex.Source);
            } catch(Exception ex) {
                Console.WriteLine("Exception Message: " + ex.Message);
                Console.WriteLine("Exception Source: " + ex.Source);
                Console.WriteLine("Stack: " + ex.StackTrace);
            } finally {
                Console.WriteLine("closing conn..."); try { conn.Close(); } catch(Exception eee){}
            }
        }
    }
}

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="DbApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <applicationSettings>
        <DbApp.Properties.Settings>
            <setting name="ConnectionString" serializeAs="String">
                <value>DATA SOURCE=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myorasvr)(PORT=1522)))(CONNECT_DATA=(SERVICE_NAME=mydb)));PERSIST SECURITY INFO=True;USER ID=MYUSER;PASSWORD=mypwd;</value>
            </setting>
        </DbApp.Properties.Settings>
    </applicationSettings>
</configuration>

Is DLL 64bit or 32bit?


visual studio comes with dumpbin command

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin>  dumpbin /headers "h:\Visual Studio 2013\Projects\EM\DotNetWeb\bin\Oracle.DataAccess.dll" | find "machine ("
             14C machine (x86)


So used in a bat file (for convenience):

rem ************************************************************************************rem * Name....: DLL_Checker.batrem * Purpose.: associate this to dll's to show if 64bit or 32bitrem * Author..: Michael Dockery <mikeinfodoc@gmail.com>rem * Date....: 02Mar2016rem ************************************************************************************@set dll=%1@IF [%dll%]==[] @set /P dll="Enter dll path\name (ex: c:\mydir\my.dll): "@echo checking %dll%"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\dumpbin" /headers "%dll%" | find "machine ("@pause

//user validation (handle good/bad parm values)

namespace EM.DotNetWeb.F01 {
 public partial class S008 : System.Web.UI.Page {
   protected void Page_Load(object sender, EventArgs e) {
    //Request.Params
     string parmFreqID=Request.QueryString["FREQ_ID"];
     switch(parmFreqID) {
        case "1": Tracing.LogMessage(screenName+ "FREQ 1=CY"); break;
        case "2": Tracing.LogMessage(screenName+ "FREQ 2=FY"); break;
        case "3": Tracing.LogMessage(screenName+ "FREQ 3=Quarterly"); break;
        case "4": Tracing.LogMessage("FREQ 4=Monthly"); break;
        default:
          String err="Invalid parm: FREQ_ID";
          Tracing.LogMessage(err);

          Session["ERR"]=err
          throw new ArgumentException(err,parmFreqID);
     }



   try{  DateTime.Parse(parmDateStart).ToString("dd-MM-yyyy");
   }catch(Exception ee){
         string err="Invalid or missing parm: DATE_START. " + ee.Message;
         Tracing.LogMessage(err);
         throw ee;
   }

     ...

onclick Run javascript before serverside onclick (via OnClientClick)
<asp:Button runat="server" ID="SUBMIT_BUTTON" 
  OnClick="SUBMIT_BUTTON_Click" 
  OnClientClick="alert('Successful Submission');"

  text="SUBMIT" UseSubmitBehavior="false"/> 

ErrorPage.aspx shows the “ERR” session variable

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ErrorPage.aspx.cs" Inherits="EM.DotNetWeb.ErrorPage" MasterPageFile="~/EM_MasterPage.Master" %>
<asp:Content ID="Body"    ContentPlaceHolderID="pagecontent" runat="server">
        <h1><%=ScreenName%></h1>
        <table cellpadding="2" width="100%" style="text-align: left; width: 100%">
            <tr>
                <td colspan="2" style="padding: 20px;">
                    <h2>Exception Occurred</h2>
                    <h3>Please click the Contact Administrator Link (above)</h3>
                    <asp:Literal runat="server" id="ERR_PAGE_OUT" EnableViewState="false" />
                </td>
            </tr>
        </table>
</asp:Content>

ErrorPage.aspx.cs code-behind

namespace EM.DotNetWeb {
    public partial class ErrorPage : System.Web.UI.Page {
        private string screenName= "Error Page";
        public string ScreenName { get { return screenName; } }
       
        protected void Page_Load(object sender, System.EventArgs e) {
            Tracing.LogMessage("ErrorPage.aspx.cs has been referenced.");
            try {
                ERR_PAGE_OUT.Text = (string)Session["ERR"];

Got App Errors?  Show/Store them!

        /* it is VERY important to accumulate app error info, else the original error causing the problem 
              will be overlaid by the latest/symptom/subsequent problem/error/exception */
        public void Application_Error(object sender, EventArgs e) {
            System.Exception lastErr= Server.GetLastError();
            if(lastErr != null) {
                WebLibrary.LogMessage("Global_Application_LastError (Global.asax.cs)...: " + lastErr.Message);
                Application["GLOBAL_ERR_LAST"] = Application["GLOBAL_ERR_LAST"] + " *****<br/> " + lastErr.Message;
                WebLibrary.LogMessage("  LastError_StackTrace...: " + Server.GetLastError().StackTrace);

                Exception lastInnerErr = lastErr.InnerException;
                if(lastInnerErr != null) {
                    System.Diagnostics.StackTrace innerStackTrace = new StackTrace(lastInnerErr);
                    WebLibrary.LogMessage("     innerException: " + lastInnerErr.Message);
                    if(lastInnerErr.Message == null || lastInnerErr.Message.Length < 1) {
                        Application["GLOBAL_ERR_INNER"] = Application["GLOBAL_ERR_INNER"] +" *****<br/> Global info is null";
                    } else {
                        Application["GLOBAL_ERR_INNER"] = Application["GLOBAL_ERR_INNER"] +" *****<br/> "
                            + lastInnerErr.Message + "   -  Target Site:" + lastInnerErr.TargetSite 
                            + " Source:" + lastInnerErr.Source + " Trace:" + lastInnerErr.StackTrace;
                    }

                    WebLibrary.LogMessage("     innerError_StackTrace...: " + lastInnerErr.StackTrace);
                    Application["GLOBAL_ERR_INNER_STACK"] = Application["GLOBAL_ERR_INNER_STACK"] + " *****<br/> " + lastInnerErr.StackTrace;
                    WebLibrary.LogMessage("     innerError_LineNum...: " + innerStackTrace.GetFrame(0).GetFileLineNumber());
                } else {
                    Application["GLOBAL_ERR_INNER"] = Application["GLOBAL_ERR_INNER"] + " *****<br/> Global.asax.cs indicates lastInnerErr is null";
                }
            } else {
                Application["GLOBAL_ERR_LAST"] = Application["GLOBAL_ERR_LAST"] + " *****<br/> " + "Global.asax.cs indicates lastErr is null"; 
            }
            WebLibrary.LogMessage("Global.asax.cs is forwarding to ErrorPage.aspx.");
            HttpContext.Current.Server.Transfer("~/ErrorPage.aspx");
        }

Super Simple Generic GridView!

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="S008.aspx.cs" Inherits="EM.DotNetWeb.F01.S008" %>
<!DOCTYPE html>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head runat="server">    <title></title></head><body>
    <form id="form1" runat="server">
       Metric History Report.
        <asp:GridView ID="gvMeasureHist" runat="server"></asp:GridView>
    </form>
</body></html>

using System;
using EM.Utilities;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Web.Configuration;
namespace EM.DotNetWeb.F01 {
    public partial class S008 : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            //Request.Params
            string parmFreqID=Request.QueryString["FREQ_ID"];
            Tracing.LogMessage("Req Parm FREQ_ID is not used:" + parmFreqID);
           
            DataTable dTbl = GetTestTable();
            displayDataTableCols(dTbl);
            gvMeasureHist.DataSource = dTbl;
            gvMeasureHist.DataBind();           
        }
        static System.Data.DataTable GetTestTable() {
            // 2 columns
            System.Data.DataTable table = new System.Data.DataTable();
            table.Columns.Add("col1num", typeof(int));
            table.Columns.Add("col2txt", typeof(string));
            // 2 rows
            table.Rows.Add(1111, "row1");
            table.Rows.Add(2222, "row2");
            return table;
        }
        //debug/testing method
        void displayDataTableCols(DataTable dTbl) {
            Tracing.LogMessage("Looping thru dataTable columns");
            foreach(DataColumn col in dTbl.Columns) {
                foreach(DataRow row in dTbl.Rows) {
                    Tracing.LogMessage(col.ColumnName + "=" + row[col.ColumnName].ToString());
                }
            }
        }
    }
}


Simple Read/loop thru a DataTable (for a GridView)

        //debug/testing method
        void displayDataTableCols(DataTable dTbl) {
            Tracing.LogMessage("Looping thru dataTable columns");
            foreach(DataColumn col in dTbl.Columns) {
                foreach(DataRow row in dTbl.Rows) {
                    Tracing.LogMessage(col.ColumnName + "=" + row[col.ColumnName].ToString());
                }
            }
        }
Generic table
    static DataTable GetTable()
    {
                // Here we create a DataTable with four columns.
                DataTable table = new DataTable();
                table.Columns.Add("Dosage", typeof(int));
                table.Columns.Add("Drug", typeof(string));
                table.Columns.Add("Patient", typeof(string));
                table.Columns.Add("Date", typeof(DateTime));
                // Here we add five DataRows.
                table.Rows.Add(25, "Indocin", "David", DateTime.Now);
                table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
                table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
                table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
                table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
                return table;
    }

Simple gridview Conditional Formatting



rename project folder for visual studio 

ensure you have no pending changes.
Remove the project from the solution, by right clicking and selecting Remove.
rename the project folder in Windows Explorer, 
Go back to Visual Studio -> Solution Explorer, rtclick solution -> Add -> Existing project

rename solution folder for visual studio 

Close Visual Studio.
backup your .sln solution file 
rename dir "Project1" to "Project2" via Windows Explorer.
notepad edit .sln file, chg all instances of "Project1" to be "Project2" 
Restart Visual Studio, and everything will work as before, but with the project in a different directory.
You can also see renaming solution manually or post which describes this manual process.



ASPX Directives  …Codes/Tags (<%...)

<%      %> code blocks
<%=     %> evaluate code expression
<%$     %> config file expression (from Web.config)
<%@     %> page directive
<%--  --%> server side comments
<%#     %> Data binding


Show session var on aspx page

Session["ERR_LAST"]="bla";
this.Page.Form.DataBind(); //this allows session vars to show on aspx page like: 

<%#HttpContext.Current.Session["BLA"] %>





<ul>
<li />Error Information..: <%#HttpContext.Current.Session["ERR_LAST"] %>
<li />Inner Error........: <%#HttpContext.Current.Session["ERR_INNER"] %>
<li />Error Page.........: <%#HttpContext.Current.Session["ERR_PAGE_OUT_MSG"] %>




<li />D-bla..: <%#HttpContext.Current.Application["D-BLA"] %>

<li />Global Error Information..: <%#HttpContext.Current.Application["GLOBAL_ERR_LAST"] %>
<li />Global Inner Error........: <%#HttpContext.Current.Application["GLOBAL_ERR_INNER"] %>
<li />Global Error Page.........: <%#HttpContext.Current.Application["GLOBAL_ERR_PAGE_OUT_MSG"] %>
</ul>


Page Life cycle



Servlet in c#/aspx.net framework?
This is done via a "Generic Handler" ashx file (which is like a simple servlet)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace EM.DotNetWeb.F01 {
    /// <summary>
    /// Summary description for GetRemarks
    /// </summary>
    public class GetRemarks : IHttpHandler {

        public void ProcessRequest(HttpContext context) {
            var parm1 = context.Request["parm1"];
            context.Response.ContentType = "text/plain";
            context.Response.Write("This is output from GetRemarks ashx.cs   (similar to servlet)");
            if(parm1 != null) context.Response.Write("Parm1:" + parm1);
        }

        public bool IsReusable {get {return false;}}
    }
}








ashx servlet-like handlers 
 cannot access Session info by default (context.Session will be null),
  so u gotta specify/implement the IRequiresSessionState interface

public class myHandler : IHttpHandler, IRequiresSessionState {
...

https://msdn.microsoft.com/en-us/library/system.web.sessionstate.irequiressessionstate(v=vs.110).aspx




Setting up a template/wizard

========================================================================================
How to: Use Wizards with Studio Project Templates 
 Studio provides the IWizard interface that, when implemented, 
  enables you to run custom code when a user creates a project from a template

   ex:  •Display custom UI that collects user input to parameterize the template.
•Add parameter values to use in the template.
•Add additional files to the template.
•Perform virtually any action allowed by the Visual Studio automation object model on a project.

The IWizard interface methods are called at various times while the project is being created, 
 starting as soon as a user clicks OK on the New Project dialog box. 
  Each interface method is obviously named:
   (ex: "RunStarted" - runs immediately when it starts to create the project, ...good place for custom code to collect user input)

Most of the code that you write for custom wizards will use the DTE object, 
 which is the main object in the Visual Studio automation object model, to customize the project. 

--------------------------------------------------------------------------------
Steps:
To create a custom template wizard which opens a Windows Form before the project is created. 
 allowing the user to add a custom parameter value that will then 
  be added to the source code during project creation. 

1.Create proj & Export it as Template (.vstemplate file) 

2.Create custom wizard assembly (implementing IWizard interface)
3.Install wizard assembly to global assembly cache (GAC)
4.Add wizard to template (aka: add .vstemplate file "WizardExtension" element)

5.Test.  (Create new project using your template wizard)

--------------------------------------------------------------------------------
1. Creating Project & Template 
 ex: console app  - displays the message specified in the user input form of the custom wizard.

 using System;
 using System.Collections.Generic;
 using System.Text;
 namespace TemplateProject{
    class WriteMessage{
        static void Main(string[] args)        {
            Console.WriteLine("$custommessage$");
   //replaced w/text entered in user input form when a project is created from the template.
        }
    }
}

Click File menu ► Export Template ► Project Template, select the project, and click Next.
  ...enter template description, select Auto-import checkbox, then click Finish.

The template now appears in the New Project dialog box, but does not use the custom wizard.


--------------------------------------------------------------------------------
1.Create class library project w/"UserInputForm" class 
2.Create class implementing the IWizard interface. "IWizardImplementation" (we only use RunStarted method here)

User Input Form: (w/textBox1 & button1)
 public partial class UserInputForm : Form{ 
    private string customMessage;
    private TextBox textBox1;
    public UserInputForm(){   //click button to store text in customMessage 
        textBox1 = new TextBox();
        this.Controls.Add(textBox1);
    }
    public string get_CustomMessage(){
        return customMessage;
    }
    private void textBox1_TextChanged(object sender, EventArgs e){
        customMessage = textBox1.Text;
        this.Dispose();
    }
}

--------------------------------------------------------------------------------
IWizardImplementation class contains method implementations for every member of IWizard. 
 this one only uses "RunStarted" method accepting 4 parms:
•Object =that can be cast to the root _DTE object, to enable you to customize the project.
•Dictionary<TKey, TValue> containing a collection of all template pre-defined parameters 
•WizardRunKind            containing info about what kind of template is being used.
•Object array             containing a set of parameters passed to the wizard by Visual Studio.

This example adds a parameter value from the user input form to the Dictionary<TKey, TValue> parameter.  
 Every instance of the $custommessage$ parameter in the project will be replaced with the text entered by the user. 

 using System;
 using System.Collections.Generic;
 using Microsoft.VisualStudio.TemplateWizard;
 using System.Windows.Forms;
 using EnvDTE;
 namespace CustomWizard{
    public class IWizardImplementation:IWizard{
        private UserInputForm inputForm;
        private string customMessage;

        // This method is called before opening any item that has the OpenInEditor attribute.
        public void BeforeOpeningFile(ProjectItem projectItem)        {        }
        public void ProjectFinishedGenerating(Project project)        {        }
        
        // This method is only called for item templates, not for project templates.
        public void ProjectItemFinishedGenerating(ProjectItem  projectItem)        {        }
        // This method is called after the project is created.
        public void RunFinished()        {        }
        public void RunStarted(object automationObject,
            Dictionary<string, string> replacementsDictionary,
            WizardRunKind runKind, object[] customParams){
            try{// Display a form to the user. The form collects input for the custom message.
                inputForm = new UserInputForm();
                inputForm.ShowDialog();

                customMessage = inputForm.get_CustomMessage();
                // Add custom parameters.
                replacementsDictionary.Add("$custommessage$", customMessage);
            }catch (Exception ex){
                MessageBox.Show(ex.ToString());
            }
        }
        // This method is only called for item templates, not for project templates.
        public bool ShouldAddProjectItem(string filePath) {
            return true;
        }        
    }
}

1.Sign the assembly with a strong name
2.Install the strong-named assembly into the global assembly cache. 

Note:  You must add the following assemblies/DLL's to your project:
1.EnvDTE.dll
2.Microsoft.VisualStudio.TemplateWizardInterface.dll
3.System.Windows.Forms.dll


--------------------------------------------------------------------------------
Add custom wizard to the template (by adding/modding ur new assembly into the vstemplate xml file)
  1.Locate/extract the .zip file that contains the template. 
  a.Tools menu ► Options ► Projects and Solutions ► view location
dflt: My Documents\Visual Studio Version\Templates\ProjectTemplates.
  2.Edit .vstemplate file in Visual Studio, After TemplateContent element, 
     add a WizardExtension Element w/the strong name of your custom wizard assembly. 
<WizardExtension>
   <Assembly>CustomWizard, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=fa3902f409bb6a3b</Assembly>
   <FullClassName>CustomWizard.IWizardImplementation</FullClassName>
</WizardExtension>




--------------------------------------------------------------------------------
Test by creating a project from your template and use the custom wizard.
1. File menu ► New Project ► locate your template ► type a name, and click OK.

Your cool/new wizard user input form should open

2.Type a custom parameter value, and click the button.
   The wizard user input form closes, and 
    a project is created from the template.

4.Solution Explorer ► rt-click source code file ► View Code.
   Notice that $custommessage$ has been replaced 
with the text entered in the wizard user input form!!!

--------------------------------------------------------------------------------

sometimes u wanna create a template which generates   multiple projects  
  belonging to a single Visual Studio solution.sln


ex: SimpleMvmRiaServices project template has three projects: 
an ASP.NET Web project, 
a Silverlight client project, and 
a Test project for unit tests.  

To create this template I first had to create individual templates for each of the three projects, 
 then extract the contents of each zip file in order 
  to combine them into a single multi-project Visual Studio template, 
    with a .vstemplate file describing the contents.  ex:

<VSTemplate Type="ProjectGroup">   
   <TemplateData>     
      <Name>WCF REST Service</Name>     <Description>REST Service Template by Tony Sneed</Description>     <ProjectType>CSharp</ProjectType>     
         <TemplateGroupID>WCF</TemplateGroupID>     <RequiredFrameworkVersion>4.0</RequiredFrameworkVersion>   
   </TemplateData> 

  <TemplateContent>     
    <ProjectCollection>       
      <ProjectTemplateLink ProjectName="$safeprojectname$.Client">         Client\Client.vstemplate</ProjectTemplateLink>       
      <ProjectTemplateLink ProjectName="$safeprojectname$.Entities">         Entities\Entities.vstemplate</ProjectTemplateLink>       
      <ProjectTemplateLink ProjectName="$safeprojectname$.Service">         Service\Service.vstemplate </ProjectTemplateLink>       
      <ProjectTemplateLink ProjectName="$safeprojectname$.Web">         Web\Web.vstemplate</ProjectTemplateLink>     
    </ProjectCollection>   
  </TemplateContent>   

  <WizardExtension>     
    <Assembly>RestTemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c9a76f51a8a9555f</Assembly>     
    <FullClassName>RestTemplateWizard.RootWizard</FullClassName>   
  </WizardExtension> 
</VSTemplate>

The template encompasses four project templates: Client, Entities, Service and Web. 
 Notice the variable, $safeprojectname$, which captures what the user entered for the project name in the New Project dialog. 
 There is also a WizardExtension element, which references an IWizard implementation.  
 IWizard allows you to control the template creation process, for example, to allow projects 
  to reference one another or to set project properties, such as the RIA Service project link required for my SimpleMvvmRiaServices template.

For my WCF REST template I wanted the Client and Service projects to both reference the Entities project, and for the Web project to reference the Service project. 
  The problem here is that within each child template, $safeprojectname$ represents the current project name. 
  There needs to be a way to pass in the root $safeprojectname$ from the parent template.  
  This is where the IWizard project comes in.

Start by creating a class library project and referencing the assembly, Microsoft.VisualStudio.TemplateWizardInterface.dll.  Create a RootWizard class that implements IWizard.  
 In the RunStarted method you can capture $safeprojectname$ from replacementParameters and 
   store it in a public static Dictionary<string,string> so that it can be captured 
     by a ChildWizard class and stored as $saferootprojectname$ in replacementParameters.


Create Simple EXE which runs on Vista+ w/DotNet


View menu - Toolbox shows the gui components which can easily be added to your windows form.
  (such as buttons, labels and text input fields, etc)



Fun/Easy combination~drowndown select list (pulled from database)

<br />Frequency:<br /><!-- from MetricEntry.Frequency table -->
  <asp:DropDownList ID="DropDownFrequency" DataSourceid="MetricEntryFrequencyDataSource" 
       DataTextField="FREQUENCY_DESCRIPTION" DataValueField="IDDESC" runat="server" ></asp:DropDownList>
  <asp:SqlDataSource ID="MetricEntryFrequencyDataSource" runat="server" 
        ConnectionString="<%$ ConnectionStrings:MetricConnectionString %>" 
        ProviderName="<%$ ConnectionStrings:MetricConnectionString.ProviderName %>" 
        SelectCommand="SELECT FREQUENCY_ID||'~'||FREQUENCY_DESCRIPTION IDDESC,  FREQUENCY_DESCRIPTION  FROM  MetricEntry.FREQUENCY "></asp:SqlDataSource>

            try {//split tilde-separated freqID and freqName
                if(!parmFreqIdAndDesc.Contains("~")) throw new Exception();
                parmFreqFriendlyName=parmFreqIdAndDesc.Substring(parmFreqIdAndDesc.IndexOf('~')+1);
                parmFreqId = parmFreqIdAndDesc.Substring(0,1);
                Tracing.LogMessage(ScreenName + " freqID:" + parmFreqId);
            } catch(Exception ee) {
                string err = "Invalid or missing parm: " + parmNameFreq + " "
                    + parmFreqIdAndDesc + " (Format expected ex: 3~Quarterly)  " + ee.Message;
                Tracing.LogMessage(err); Application["ERR_PAGE_OUT_MSG"] = err;
                throw new ArgumentException(err, parmNameFreq);
            }

Export aspx grid as html table (named.xls to open with excel)

        /// <summary>
        /// Export aspx grid rows/columns into html_table as excel_xls
        /// grid Headers as TH elements, grid detail row cells as TD html elements
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnExportHTML_Click(object sender, EventArgs e) {//export to excel
            Tracing.LogMessage("S001 HTML Export Requested");
            Response.Clear();
            Response.Buffer = true;
            Response.AddHeader("content-disposition", "attachment;filename=" +parmFreqFriendlyName+"_HIST_html.xls");
            Response.Charset = "";
            Response.ContentType = "application/text";

            int colCount = gvMeasureHist.HeaderRow.Cells.Count;
            int rowCount = gvMeasureHist.Rows.Count;
            Tracing.LogMessage(ScreenName + " HTML Export Starting.  RowCount:" + rowCount + "  CellCount:" + colCount);
            string commaSep = ",", newLine = "\r\n";
            StringBuilder sb = new StringBuilder();
            sb.Append("<html><body><table></tr>");

            for(int k = 0; k < colCount; k++) {//HEADER 
                //Tracing.LogMessage("S008 header "+k); //+":" + gvMeasureHist.Columns[k].HeaderText);
                sb.Append("<th>" + gvMeasureHist.HeaderRow.Cells[k].Text + "</th>");
            } sb.Append("</tr>" + newLine);

            for(int i = 0; i < rowCount; i++) { //CSV DETAILS
                sb.Append("<tr>" + newLine);
                for(int k = 0; k < colCount; k++) {
                    //Tracing.LogMessage("S008 cell " + i + "      row " + i ); //+ gvMeasureHist.Rows[i].Cells[k].Text);
                    string cellVal = gvMeasureHist.Rows[i].Cells[k].Text;
                    cellVal = cellVal.Replace(System.Environment.NewLine, " ");  //remove line feeds in any/all incoming text cells
                    cellVal = cellVal.Replace("&nbsp;", "-");  //replace html nonblank/spaces with a dash
                    cellVal = cellVal.Replace(commaSep, "  ");  //change commas to double spaces
                    sb.Append("<td>" + cellVal + "</td>"); //Tracing.LogMessage("row:" + i + " col:" + k + " text:" + cellVal);
                } sb.Append("</tr>" + newLine);
            }
            sb.Append("</table></body></html>");
            Tracing.LogMessage(ScreenName + " Export Complete");
            Response.Output.Write(sb.ToString());
            Response.Flush(); Response.End();
        }

Grid RowDataBound fun

        protected void GRID_PAGE_TEST_RowDataBound(object sender, GridViewRowEventArgs e) {
            //((GridView)sender).DataKeys[e.Row.RowIndex].Value.ToString();
            IEnumerator ie = e.Row.Cells.GetEnumerator();
            while(ie.MoveNext()) {
                DataControlFieldCell cell = (DataControlFieldCell)ie.Current;
                logIt("dta:"+cell.Text +"   hdr: " + cell.ContainingField.HeaderText);
            }
            if(e.Row.RowType == DataControlRowType.Header){
                  foreach (DataControlFieldCell Cell in e.Row.Cells){
                      string cellTextOriginal = Cell.ContainingField.ToString();
                      logIt("cell: "+cellTextOriginal);
                      logIt("hdr: "+Cell.ContainingField.HeaderText);                      
                      Cell.Text = cellTextOriginal.Replace("_", " ");
                  }
            }

Build files

build consists of
 compiling .c, .cpp, cs files into .o or .obj machine code files (which cannot be run/executed)
 linking creates exe from obj files. it tries to find ref's for functions

pdb files = symbols (source code line#'s and function names ...for debugging)
  so even for web apps, just copy the auto generated pdb (program debug database) file
    to the same dir as your exe (or the bin file of your webapp)
     and automagically the stack line numbers will be shown!

MS Visual Studio, command line tool :

dumpbin /exports <nameofdll>

Debub Symbols/Line numbers (aka: pdb "Program Debug Database")


Assembly Info

Visual studio builds continue even if an assembly is not found
 If the code has no actual references to the assembly.

If the code DOES have references, the build fails with an error (warning MSB3245) that looks
 as if the code were using unknown types or namespaces.

assemblies resolution sequence:

  1. .csproj <HintPath> element 
  2. The project output path (debug or release folder)
  3. The GAC (Global assembly cache) highest version found (if "Specific Version" is false)
You might need to "Clean" the project after setting the hintpath.
hint path only helps with compiling

When "Specific Version" is true, Visual Studio decides based on
 .csproj <SpecificVersion> & presence/absence of version info in the assembly reference)

Example assembly reference with version information:
  <Reference Include="SharedLib, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
    <SpecificVersion>True</SpecificVersion>
    <HintPath>..\..\Dir1\SharedLib.dll</HintPath>
  </Reference>

 And without:
   <Reference Include="SharedLib">
[...]

--------------
sample program to pull/show it  (Note: you MUST use/include the reflection package)

using System;
using System.Reflection;
using System.Windows.Forms;

[assembly: AssemblyVersion("2016.8.01.1")]
[assembly: AssemblyCompany("MYCO")]
[assembly: AssemblyTitle("Helpful classes: UtilsFTP, UtilsFile, UtilsSecureFTP, UtilsWeb and UtilsDatabase")]
[assembly: AssemblyProduct("Depends on Oracle.ManagedDataAccess.dll, WinSCP.dll and WinSCP.exe")]


namespace NotificationArea_WebformApp {
partial class AboutBox : Form{
public AboutBox(){
InitializeComponent();
this.Text = String.Format("About {0}", AssemblyTitle);
this.labelProductName.Text = AssemblyProduct;
this.labelVersion.Text = String.Format("Version {0}", AssemblyVersion);
this.labelCopyright.Text = AssemblyCopyright;
this.labelCompanyName.Text = AssemblyCompany;
this.textBoxDescription.Text = AssemblyDescription;
}
#region Assembly Attribute Accessors
public string AssemblyTitle{
get{    object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0){
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != "") return titleAttribute.Title;
}
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
}
}
public string AssemblyVersion{
get{return Assembly.GetExecutingAssembly().GetName().Version.ToString();}
}
public string AssemblyDescription{
get{    object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length == 0) return "";
return ((AssemblyDescriptionAttribute)attributes[0]).Description;
}
}
public string AssemblyProduct{
get{    object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length == 0)  return "";
return ((AssemblyProductAttribute)attributes[0]).Product;
}
}
public string AssemblyCopyright {
get{    object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length == 0) return "";
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
}
public string AssemblyCompany{
get{    object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length == 0) return "";
return ((AssemblyCompanyAttribute)attributes[0]).Company;
}
}
#endregion
}
}




view/edit c# csproj file from Visual Studio:
 solution explorer-> rtclick project -> Unload Project
 rtclick->edit the now "unavailable" project 
 save/close csproj then rtclick Reload project 


Simple class reflection class to show the public methods of a class

using System;
using SharedLib;
using System.Text;
using System.Reflection;
using System.Windows.Forms; 
namespace SharedLibTest {
    class Program {
        static void Main(string[] args) {
            Boolean debug = false; StringBuilder sb = new StringBuilder();
            if(debug) {//use for temp testing
                //Console.WriteLine("Press any key to exit.");
                //System.Console.ReadKey();
            } else {//the normal processing goes here
                WinForm1 form1 = new WinForm1();
                string guiTitle="ShareLib classes and methods Info";
                form1.label1.Text = guiTitle; //set label "Modifier" to Public 
                form1.Text = guiTitle;
                form1.Visible = true;
                form1.textBox1.Text = "Please wait for all class tests to complete..."+Environment.NewLine;

                form1.textBox1.AppendText(GetClassDetails(typeof(UtilsClass)));
                UtilsClass.Test();
                form1.textBox1.AppendText(GetClassDetails(typeof(UtilsFile)));
                UtilsFile.Test();
                form1.textBox1.AppendText(GetClassDetails(typeof(UtilsDatabase)));
                UtilsDatabase.Test();
                form1.textBox1.AppendText(GetClassDetails(typeof(UtilsWeb)));
                UtilsWeb.Test();
                form1.textBox1.AppendText(GetClassDetails(typeof(UtilsFtp)));
                UtilsFtp.Test();
                form1.textBox1.AppendText(GetClassDetails(typeof(UtilsWinSCP))); //the winscp test is slow
                UtilsWinSCP.Test();               

                form1.textBox1.AppendText("********************************");
                form1.textBox1.AppendText("Complete.");
                form1.textBox1.AppendText("********************************");
                Application.Run(form1);
                
                return;
            }

        }
        /// <summary>
        /// Show public methods for class
        /// Pass class in via 
        /// </summary>
        /// <param name="classType"></param>
        public static string GetClassDetails(Type classType) {
            StringBuilder classInfo = new StringBuilder();
            AppendAndPrint("*************************************************************************", classInfo,true);
            AppendAndPrint("  " + classType.Name + " Public Methods:", classInfo, true);
            AppendAndPrint("*************************************************************************", classInfo, true);
            //MethodInfo[] methodInfos = classType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
            MethodInfo[] methodInfos = classType.GetMethods();
            foreach(MethodInfo mi in methodInfos) {
                if(mi.IsPublic) {
                    AppendAndPrint("          " + mi.Name + "(", classInfo, false);
                    foreach(ParameterInfo pi in mi.GetParameters()) {
                        AppendAndPrint(" " + pi.Name + "_" + pi.ParameterType, classInfo, false); //" "+pi.Position);
                    }
                    AppendAndPrint("  )", classInfo, true);
                }
            }
            return classInfo.ToString()+Environment.NewLine;
        }
        public static StringBuilder AppendAndPrint(String s, StringBuilder sbldr, Boolean lineFeed) {
            if(lineFeed) s=s+Environment.NewLine;
            sbldr.Append(s);
            Console.Write(s);            
            return sbldr;
        }
    }//class
}//namespace

Dynamically create grid with 1-row-table containing controls 

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using SharedLib; //has oracle functions in it from the managed driver
namespace WebAppTest {
    public partial class TestOracle : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            UtilsDatabase db = new UtilsDatabase(UtilsDatabase.ConnectionString_MYCOQ, UtilsDatabase.OraManagedProviderName);
            GridView GRID1=new GridView();
            UtilsWeb.LoadGridFromDb(GRID1,db, "select * from dual");
            string dt = UtilsClass.GetNowYYYYMMDD(), sql = "insert into temptest values('" + dt + "')";
            UtilsClass.LogToVisualStudioOutputWindow("Running sql: "+sql);
            string result = db.runInsertStatement(sql);
            UtilsClass.LogToVisualStudioOutputWindow("insert result: " + result);
            db.closeConnection();
            form1.Controls.Add(GRID1);

            System.Web.UI.HtmlControls.HtmlGenericControl createDiv = new
            System.Web.UI.HtmlControls.HtmlGenericControl("DIV");
            createDiv.ID = "RESULT_DIV";
            createDiv.InnerHtml = sql + " " + result;
            this.Controls.Add(createDiv);
        }
    }
}

List all parms (post or get)

        /// <summary>
        /// List post request parms (for debug purposes)
        /// Usage when called from Page_Load: <para/>
        /// ListRequestPostParms(Request);
        /// </summary>
        /// <param name="req"></param>
        public static void ListRequestPostParms(HttpRequest req) {
            logIt("***************************");
            logIt("Listing POST request parms:"); 
            foreach(string key in req.Form.Keys) logIt(key.ToString()+"="+req.Form[key]);
            logIt("***************************");
        }

        /// <summary>
        /// List GET request parms (for debug purposes) <para/>
        /// Usage when called from Page_Load: <para/>
        /// ListRequestGetParms(Request);
        /// </summary>
        /// <param name="req"></param>
        public static void ListRequestGetParms(HttpRequest req) {
            logIt("***************************");
            logIt("Listing GET/QueryString request parms:");
            foreach(string key in req.QueryString.Keys) logIt(key.ToString() + "=" + req.QueryString[key]);
            logIt("***************************");
        }


Super Simple example of using var in application context:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AppVar.aspx.cs" Inherits="WebAppTest.AppVar" %>
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">    <title></title></head><body>

    <form id="form1" runat="server">
    <div>
    <%=Application["APPVAR1"] %>
    </div>
    </form>

</body></html>

using System;

namespace WebAppTest {
    public partial class AppVar : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            Application["APPVAR1"] = "happy1";
        }
    }
}





FileWatcher


        /// <summary>
        ///  Listens to the file system change notifications and raises events when a dir or file changes. <para/>
        ///  however windows vista+ only changes a files modified date when it is closed, <para/>
        ///  So filewatcher is not useful to monitor server logs
        /// </summary>
        public void CreateFileWatcher() {
            watcher = new FileSystemWatcher();
            //watcher.Path = @"C:\temp\";
            watcher.Path = @"C:\Program Files\tomcat8\logs\";
            //watcher.Filter = "*.txt"; //only catch TXT files.
            watcher.Filter = "*stdout*.log";
            watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.LastAccess;
            watcher.Created += new FileSystemEventHandler(watcher_FileCreated); //take action if txt file created
            watcher.Changed += new FileSystemEventHandler(watcher_Changed);
            watcher.EnableRaisingEvents = true;
        }

        void watcher_Changed(object sender, FileSystemEventArgs e) {
            watcher.EnableRaisingEvents = false; //prevent multiple calls from 1 event
            string msg = "File is changing: " + e.Name;
            Console.WriteLine(msg);
            AboutBox box = new AboutBox();
            box.textBoxDescription.Text = msg;
            box.ShowDialog();
            watcher.EnableRaisingEvents = true;
        }
        void watcher_FileCreated(object sender, FileSystemEventArgs e) {
            string msg = "A new *.txt file has been created! "+e.Name;
            Console.WriteLine(msg); //new .TXT file was created in C:\Temp\
            AboutBox box = new AboutBox();
            box.textBoxDescription.Text = msg;          
            box.ShowDialog();
        }


Create simple service from visual studio

  create new windows service project
  add code for onstart and onstop
  right click to add installer (which adds installer for service and for job)
  then run installutil myexename.exe
  Note: the exe must be in a folder on the local drive (it cannot be on a network share/dir)

 optionally create a "setup and deploy" job to create an msi installer


System tray (notification area) app to monitor log file via background worker

using System.Threading.Tasks;
using System.Threading;
using System;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using NotificationArea_WebformApp.Properties;
using System.IO;
using System.ComponentModel; //BackgroundWorker 
namespace NotificationArea_WebformApp {
    /// <summary>
    /// Create icon in tray w/menu+events
    /// </summary>
class NotifyIconer : IDisposable{
NotifyIcon ni;
        FileSystemWatcher watcher;
        private BackgroundWorker bw = new BackgroundWorker();
        public NotifyIconer() { 
            ni = new NotifyIcon();
            this.DisplayIconInTray();
            bw.WorkerReportsProgress = true;
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += new DoWorkEventHandler(bw_DoWork);
            bw.RunWorkerAsync();
            Application.Run();
            this.Dispose();
        }
        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) {
            AboutBox box = new AboutBox();
            box.textBoxDescription.Text = "it changed";
            box.ShowDialog();
        }
        void bw_DoWork(object sender, DoWorkEventArgs e) {
            BackgroundWorker worker = sender as BackgroundWorker;
            string FileName=@"C:\Program Files\tomcat8\logs\tomcat8-stdout.2016-07-29.log";
            using(StreamReader reader = new StreamReader(new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) {
                long lastMaxOffset = reader.BaseStream.Length;     //start at the end of the file
                while(true) {
                    System.Threading.Thread.Sleep(5000); 
                    if((worker.CancellationPending == true)) {
                        e.Cancel = true;
                        break;
                    } else {
                        if(reader.BaseStream.Length == lastMaxOffset) continue; //file size did not change, continue idle loop
                        reader.BaseStream.Seek(lastMaxOffset, SeekOrigin.Begin); //goto prior end of the file
                        string line = ""; StringBuilder sb = new StringBuilder();
                        while((line = reader.ReadLine()) != null) {
                            sb.Append(line + Environment.NewLine);
                            //worker.ReportProgress(10);
                        }
                        if(sb != null && sb.Length > 0) {//show log to user
                            AboutBox box = new AboutBox();
                            box.textBoxDescription.Text = sb.ToString();
                            box.ShowDialog();

                        }
                        lastMaxOffset = reader.BaseStream.Position;
                    }
                }
            }
        }
        /* using(NotifyIconer notifyIconer = new NotifyIconer()) {
                 notifyIconer.DisplayIconInTray(); // Show the system tray icon
                 notifyIconer.CreateWatcher(); // Show the system tray icon
                 Application.Run();  } */

        /// <summary>
        /// Set text, add menu and click event handler
        /// </summary>
        public void DisplayIconInTray() {//icon in the system tray.
ni.MouseClick += new MouseEventHandler(ni_MouseClick);
ni.Icon = Resources.mis_logo;
ni.Visible = true;
            ni.Text = "Logfile monitor program written by Doc"; //icon mousehover text
            ni.ContextMenuStrip = CreateNotificationIconMenu(); //About, exit, etc
        }
public void Dispose(){ni.Dispose();}
        void ni_MouseClick(object sender, MouseEventArgs e) { // Start Windows Explorer.
if (e.Button == MouseButtons.Left)  Process.Start("explorer", null); 
}

        /// <summary>
        /// Menu
        /// </summary>
        /// <returns></returns>
        public ContextMenuStrip CreateNotificationIconMenu() {
            ContextMenuStrip menu = new ContextMenuStrip();
            ToolStripMenuItem item;

            item = new ToolStripMenuItem(); item.Text = "Explorer";
            item.Click += new EventHandler(Explorer_Click);
            item.Image = Resources.Explorer; // Windows Explorer.
            menu.Items.Add(item);

            item = new ToolStripMenuItem(); item.Text = "About";
            item.Click += new EventHandler(About_Click); //AboutBox().ShowDialog();
            item.Image = Resources.About;
            menu.Items.Add(item);

            ToolStripSeparator separator = new ToolStripSeparator();
            menu.Items.Add(separator);

            item = new ToolStripMenuItem(); item.Text = "Exit";
            item.Click += new System.EventHandler(Exit_Click);
            item.Image = Resources.Exit;
            menu.Items.Add(item);
            return menu;
        }
        void Explorer_Click(object sender, EventArgs e) { Process.Start("explorer", null); }
        void About_Click(object sender, EventArgs e) { new AboutBox().ShowDialog(); }
        void Exit_Click(object sender, EventArgs e) {
            bw.CancelAsync();
            Application.Exit();
        }
        
}//class
}//ns




If issues with IIS and the oracle.manageddataaccess dll driver


Exception Details: System.IO.FileLoadException: Could not load file or assembly 

'Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. 

ensure your all your iis web features are installed
  then run  %windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i

simply download/unzip the ODP 64bit 

then run this (using your oracle_home path)

install_odpm.bat C:\app\product\11.2.0\client_1 x64

then ensure 

C:\windows\microsoft.net\framework64\v4.0.30319\Config\machine.config
   ...
     <system.data>
        <DbProviderFactories>
           has this one
 <add name="ODP.NET, Managed Driver"   invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />


Also verify your project's .csproj file has the ref included (with proper hint path)
  <ItemGroup>
    <Reference Include="Oracle.ManagedDataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>C:\app\DLLs\Oracle.ManagedDataAccess.dll</HintPath>

    </Reference>

JSON - working sample

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TrafficCounterJSON {
    class Program {
        static void Main(string[] args) {
            String responseJsonString=GetReleases("https://indot.ms2soft.com/TDMS/Services/LocationDataApi/GetStationSummary?key=7647b037-3f0a-474f-a4cb-41e02e17371f&localId=410541");
            Console.Out.WriteLine("json response:" + responseJsonString);
            string jsonString = @"{
              'Email': 'james@example.com',
              'Active': true,
              'CreatedDate': '2013-01-20T00:00:00Z',
              'Roles': [
                    'User',
                    'Admin'
              ]
            }";
            Account account = Newtonsoft.Json.JsonConvert.DeserializeObject<Account>(jsonString);
            Console.WriteLine("email is : "+account.Email);
        }
        static public string GetReleases(string url) {
            var client = new System.Net.WebClient();   //client.Headers.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);            
            var response = client.DownloadString(url);            
            return response;
        }
    }
    public class Account {
        public string Email { get; set; }
        public bool Active { get; set; }
        public DateTime CreatedDate { get; set; }
        public IList<string> Roles { get; set; }
    }
}

Comments

Popular Posts