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 bracepress 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"]);
}
}
beanyIdToFind = "DONTEXIST";
public class Beany {
/// <summary>
/// <summary>
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;
}
}
}
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 >=
/// 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;
}
}
}
------------------------------------------
<!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);
}
}
}
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());
}
}
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.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
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
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):
So used in a bat file (for convenience):
//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>
<%#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(" ", "-"); //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
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 foundIf 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:
- .csproj <HintPath> element
- The project output path (debug or release folder)
- The GAC (Global assembly cache) highest version found (if "Specific Version" is false)
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 projectadd 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; }
}
}
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
Post a Comment