Programming Journal C#, Java, SQL and to a lesser extent HTML, CSS, XML, and regex. I made this so other programmers could benefit from my experience.

Tuesday, December 23, 2008

Add Google Charts with .NET

Add Google Charts with .NET.
Go to: http://code.google.com/p/googlechartsharp/
Download DLL.
Save and Unzip to location.

From your project, add reference.
Select DLL.
Copy source code from below:

// using GoogleChartSharp;

int[] data = new int[] { 40, 30, 20, 10, 0 };

// Specify chart width and height in pixels
LineChart chart = new LineChart(150, 150);

// SetData will accept int[] and float[] for single data sets
chart.SetData(data);

string imageUrl = chart.GetUrl();
Image1.ImageUrl = imageUrl;
Run. Enjoy. Modify. Visit these sites for more:
http://groups.google.com/group/google-chart-api/web/useful-links-to-api-libraries

References:
http://code.google.com/p/googlechartsharp/
http://code.google.com/p/googlechartsharp/wiki/UsageExamples

Get the ApplicationName for Stored Procedure Parameter

Sometimes the ApplicatonName is necessary for Membership stored procedures. You can access the ApplicationName as follows:

string appName = Membership.ApplicationName;


References: http://msdn.microsoft.com/en-us/library/system.web.security.membership.applicationname(VS.80).aspx

Get the Current Time for Database Storage

To get the current datetime in UTC format in .net use following:

DateTime dateUTC = DateTime.Now.ToUniversalTime();
You can then store this date in your database.
If you want to display it back to local time use:


DateTime dateLocal = dateUTC.ToLocalTime();


Reference: http://forums.asp.net/t/1217716.aspx

The Difference Between NVARCHAR and VARCHAR

The main difference between NVARCHAR and VARCHAR is that NVARCHAR extra space allows for easier multi-language support. Therefore, I switched my database's VARCHARs to NVARCHARS.

References: http://july-code.blogspot.com/2008/03/differences-between-varchar-and.html

Accessing ConnectionString from CodeBehind

Accessing a ConnectionString from CodeBehind requires your connection string to be defined in the web.config file.

Then use this source code:

ConnectionString = System.Configuration.ConfigurationManager.AppSettings["MySetting"].ToString();

I customized my BasePage with a utility function as follows:

public string getConnectionString(string vConnectionString)
{
System.Configuration.Configuration rootWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
System.Configuration.ConnectionStringSettings connString = null;
string connectionString = string.Empty;
if (0 < rootWebConfig.ConnectionStrings.ConnectionStrings.Count)
{
connString =
rootWebConfig.ConnectionStrings.ConnectionStrings[vConnectionString];
if (connString != null)
connectionString = connString.ConnectionString;
}
return connectionString;
}

References: http://forums.asp.net/p/1353594/2770309.aspx
http://msdn.microsoft.com/en-us/library/ms178411(VS.80).aspx

Use ConnectionString Web.config

I setup the ConnectionString in my Web.config file and encountered a "'ConnectionStringSettings' is not defined error. The solution was to add the 'system.configuration' library to the project! (Project, Add reference.., then find the library then add it!).

References: http://forums.asp.net/p/1047730/1475561.aspx#1475561

Keeping a DropDownList's DataSource Updated

The DropDownList does not manage selected state like other controls. Therefore, I use a Session variable to store an index to keep track of the currently selected item:

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Session["listId"] = ddlList.SelectedValue;
GridViewStocksInLists.DataBind();
}
}

Now, I add the SelectedIndexChanged event with the following code:

protected void ddlList_SelectedIndexChanged(object sender, EventArgs e)
{
Session["listId"] = ddlList.SelectedValue;
GridViewStocksInLists.DataBind();
}

Reference: http://www.velocityreviews.com/forums/t123449-problem-with-formview-and-dropdownlists.html

Use a CustomControl to Set UserId and Use as a DataBindable Property

Use a CustomControl (named MembershipUser) to Set UserId and Use as a DataBindable Property. Create a MembershipUser CustomControl that has a property named Value that can be DataBound. For example MembershipUser1.Value would fetch the userId:


[Browsable (true)]
public string Value
{
get
{
MembershipUser currentUser;
currentUser = Membership.GetUser();
if (currentUser == null)
return string.Empty;
return currentUser.ProviderUserKey.ToString();
}
}
Reference: This is from http://aspnet.4guysfromrolla.com/articles/110106-1.aspx

Be Careful About uniqueId Parameter in Stored Procedure

Here is an error I received when my UniqueId parameter in a stored procedure was not valid:



Server Error in '/stockmonger.com' Application.
Conversion failed when converting from a character string to uniqueidentifier.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: Conversion failed when converting from a character string to uniqueidentifier.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.


I corrected to make sure the parameter was a valid uniqueId paramater and not null.

Modifying DataBound Hyperlinks Text

Modifying a GridView's Databound Hyperlink text since I couldn't do this easily in the ItemTemplate, I moved the Replace function to the DataBound of the GridView:


protected void GridViewStocksInLists_DataBound(object sender, EventArgs e)
{
int rowId;
string imgUrl;
string navUrl;
for (rowId=0; rowId<GridViewStocksInLists.Rows.Count;rowId++) {
imgUrl = string.Empty;
navUrl = string.Empty;
imgUrl = ((HyperLink)GridViewStocksInLists.Rows[rowId].FindControl("hlChart")).ImageUrl.Replace('$', '^');
((HyperLink)GridViewStocksInLists.Rows[rowId].FindControl("hlChart")).ImageUrl = imgUrl;
navUrl = ((HyperLink)GridViewStocksInLists.Rows[rowId].FindControl("hlChart")).NavigateUrl.Replace('$', '^');
((HyperLink)GridViewStocksInLists.Rows[rowId].FindControl("hlChart")).NavigateUrl = navUrl;
}
}
This replaced $ with ^ in my HyperLink.

Here is the GridView that contains the HyperLink:

<asp:GridView ID="GridViewStocksInLists" runat="server" DataSourceID="SqlDataSourceGetStocksInList">
<RowStyle CssClass="tableAnalysisRow" />
<HeaderStyle CssClass="tableAnalysisHeader" />
<AlternatingRowStyle CssClass="tableAnalysisAlternatingRow" />
<Columns>
<asp:TemplateField HeaderText="Chart">
<ItemTemplate>
<asp:HyperLink ID="hlChart" runat="server"
ImageUrl='<%# Eval("Symbol", "http://chart.finance.yahoo.com/c/0b/d/{0}").ToLower() %>'
NavigateUrl='<%# Eval("Symbol", "http://finance.yahoo.com/q/bc?s={0}&t=1y").ToLower() %>' >
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

References: http://forums.asp.net/p/1263726/2542303.aspx#2542303

Remove HTML Tags

Remove HTML Tags from a string:

public static string RemoveHtml(string txt)
{
return Regex.Replace(txt, @"<[^>]*>", string.Empty);
}


Reference: http://www.webpronews.com/expertarticles/2006/12/01/aspnet-remove-html-tags-from-a-string

Wednesday, December 17, 2008

Using AutoComplete Ajax Control With Separate ID Field from Name Field

In the previous post, I detailed how to use the SQL stored procedure to select matches.

AutoComplete Extender offers a convenient way to select values froma TextBox. One problem is that multiple details can be displayed, but the whole text is selected by default. I wanted to allow multiple AutoCompletes, select the id without the other details and append the appropriate delimeter in between entries. First, I setup the WebService method. Note that the Stock object has Symbol and Name properties:

[WebMethod]
public string[] GetStocksInPrefix(string prefixText, int count)
{
int curCount = 0;
if (count == 0)
{
count = 10;
}
List<string> items = new List<string>();
JavaScriptSerializer jss = new JavaScriptSerializer();
string[] stocks = null;
string connectionString = getConnectionString("ConnectionString");
SqlDataReader rdr = null;
SqlConnection conn = new SqlConnection(connectionString);
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("sproc_aspnet_GetStocksByPrefix", conn);
try
{
command.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
command.Parameters.AddWithValue("@Prefix", prefixText+"%");
rdr = command.ExecuteReader();
string tmp = string.Empty;
Stock _stock = null;
while (rdr.Read() && curCount<count )
{
_stock = new Stock(rdr["Symbol"].ToString(), rdr["Name"].ToString(), rdr["Exchange"].ToString());
tmp = rdr["Symbol"] + "\t" + rdr["Name"];
items.Add(AutoCompleteExtender.CreateAutoCompleteItem(tmp, jss.Serialize(_stock)));
curCount++;
}
command.Parameters.Clear();
}
catch (Exception ex)
{
}
finally
{
if (rdr != null) rdr.Close();
if(conn!=null) conn.Close();
}
return items.ToArray();
}


Then, I add the javascript event, 'OnSymbolSelected',to the OnClientItemSelected event in the AutoComplete Extender:

<asp:TextBox ID="txtSymbols" runat="server" Width="300px"></asp:TextBox>
<cc1:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server"
TargetControlID="txtSymbols" ServiceMethod="GetStocksInPrefix"
ServicePath="~/WebServiceAutoCompleteSymbol.asmx" MinimumPrefixLength="2"
CompletionListHighlightedItemCssClass="watermark" CompletionSetCount="10"
DelimiterCharacters=", "
CompletionListElementID="Symbol"
CompletionListItemCssClass="watermarkMatch"
EnableCaching="true" CompletionInterval="1000" OnClientItemSelected="OnSymbolSelected"
>
</cc1:AutoCompleteExtender>


Finally, add the javascript function to the aspx page. This function reads the Stock object into results, takes the SelectedText and gets the original string before the new text was completed by replacing the completed text with an empty string. If it is an additional field (that does not contain ' ' or ',', then only the id (symbol in this case) is added. Othewise, the original id plus the ' ' delimeter and the new id is added:

<script type="text/javascript" language="javascript">
function OnSymbolSelected(source, eventArgs)
{
var results = eval('(' + eventArgs.get_value() + ')');
if (results.symbol != null) {
var symbols = document.getElementById('<%= txtSymbols.ClientID %>').value;
var original = symbols.replace((results.symbol+'\t'+results.name),'');
if (original.indexOf(' ')>0 || original.indexOf(',')>0)
document.getElementById('<%= txtSymbols.ClientID %>').value = original + (' '+ results.symbol);
else
document.getElementById('<%= txtSymbols.ClientID %>').value = results.symbol;
}
}
</script>


References: http://ziqbalbh.wordpress.com/2008/06/11/google-like-autocomplete-suggestions/
http://www.tizag.com/javascriptT/javascript-string-replace.php
http://techron.blogspot.com/2008/04/reading-textbox-or-other-control-values.html

Using LIKE in SQL

Be careful in the order of parameters while using LIKE in T-SQL. The following stored procedure did not work @Prefix LIKE dbo.aspnet_Stocks.Name. It must be reversed:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sproc_aspnet_GetStocksByPrefix]
@Prefix as varchar(50)=NULL
AS
BEGIN
SELECT *
FROM dbo.aspnet_Stocks
WHERE ((Symbol LIKE @Prefix) OR ( [Name]LIKE @Prefix))
RETURN 0
END

This was used in an AutoComplete AJAX control. The following reference describes the setup.

Reference: http://www.aspdotnetcodes.com/AutoComplete_From_Database.aspx

A more efficient stored procedure would use a FullText Catalog indexed on a Text Column as described here: http://support.microsoft.com/?kbid=916784

Tuesday, December 16, 2008

Sorting a GridView

Sorting a GridView with a DataSource requires an external storage variable for a the last SortDirection. First, I call the GridViewReport_Sorting in the Sorting event in the GridView. A GridView has e.SortExpression and e.SortDirection. I combine the two to form a unique Session variable and then set the SortDirection to compare at later sorts:

protected void GridViewReport_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dt;
DataView dv;
dt = (DataTable)Cache["dvStocks"];
dv = new DataView(dt);
string direction = SortDirection.Descending.ToString();
string curDirecton = SortDirection.Ascending.ToString(); // set to default
string key = string.Concat(e.SortExpression, e.SortDirection);
if(Session[key]!=null) {
curDirecton = (string)Session[key];
}
if (curDirecton.Contains("Ascending"))
{
direction = Global.DESC; //DESC
Session[key] = SortDirection.Descending.ToString();
}
else
{
direction = Global.ASC; //ASC
Session[key] = SortDirection.Ascending.ToString();
}
dv.Sort = e.SortExpression + " " + direction;
Cache["dtCalculated"] = dv.ToTable();
GridViewReport.DataSource = dv;
GridViewReport.DataBind();
}

Reference: http://forums.asp.net/t/825118.aspx

Monday, December 15, 2008

Using static strings and objects to increase performance and maintainence

I found this global variable article below to help me with using static strings and objects to increase performance and maintainence.

For example, suppose I have an error message, "Error: ", that I might want to change to "There was a problem: ". Instead of search and replace n times, I could just use a static string variable to change the string value.

Sample Global class:

/// <summary>
/// Summary description for Global
/// </summary>
public static class Global
{
public static string CSS_HIDDEN
{
get { return "hidden"; }
}
public static string CSS_EMPTY
{
get { return string.Empty; }
}
public static string CSS_CONTENT
{
get { return "content1"; }
}
public static string ERROR_HEADER_HTML
{
get { return "<red>There was a problem:</red></br>"; }
}
public static string ERROR_HEADER
{
get { return "There was a problem:"; }
}
}
Then one just accesses it with Global.ERROR_HEADER. Notice that there is no declarative instantiation for the static class.

Reference: http://dotnetperls.com/Content/Global-Variables-ASPNET.aspx

Sunday, December 14, 2008

Use securitytrimming to limit role views of Menu and SiteMap

Use securitytrimming to limit role views of Menu and SiteMap.

Modify the Web.config file's configuration tag with:


<system.web>
<siteMap defaultProvider="secureProvider">
<providers>
<add name="secureProvider" type="System.Web.Xml




Provider"

siteMapFile="web.sitemap" securityTrimmingEnabled="true"/>
</providers>
</siteMap>
</system.web>
Then modify Web.sitemap to make sure roles parameter is set to * or admin. Notice how I explicitly set the nodes roles parameter in the links outside the website

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="SiteMap.aspx" title="Site Map" description="Site Map">
<siteMapNode url="Default.aspx" title="Home" description="Home" roles="*">
<siteMapNode url="Login.aspx" title="Login/Logout" description="Login or Logout" />
<siteMapNode url="About.aspx" title="About" description="About" />
</siteMapNode>
<siteMapNode url="~/Tools/Tools.aspx" title="Tools" description="" roles="*">
<siteMapNode url="~/Tools/GrowthAnalysis.aspx" title="Growth Analysis" description="" />
<siteMapNode url="~/Tools/FundamentalAnalysis.aspx" title="Fundamental Analysis" description="" />
<siteMapNode url="~/Tools/PriceToSalesAnalysis.aspx" title="Price To Sales Analysis" description="" />
<siteMapNode url="~/Tools/TechnicalAnalysis.aspx" title="Technical Analysis" description="" />
</siteMapNode>
<siteMapNode url="~/MyLists/MyLists.aspx" title="My Lists" description="" roles="*">
<siteMapNode url="~/MyLists/Management.aspx" title="Management" description="" />
<siteMapNode url="~/MyLists/Tracker.aspx" title="Tracker" description="" />
</siteMapNode>
<siteMapNode url="~/MarketWatch/MarketWatch.aspx" title="Market Watch" description="" roles="*">
<siteMapNode url="~/MarketWatch/MarketSummary.aspx" title="Market Summary" description="" />
<siteMapNode url="~/MarketWatch/SectorSummary.aspx" title="Sector Summary" description="" />
<siteMapNode url="~/MarketWatch/IntermarketSummary.aspx" title="Inter-market Summary" description="" />
<siteMapNode url="~/MarketWatch/WorldMarketSummary.aspx" title="World Market Summary" description="" />
</siteMapNode>
<siteMapNode url="~/Media.aspx" title="Media" description="" roles="*">
<siteMapNode url="http://www.bloomberg.com/news/av/" title="Bloomberg Audio/Video" description="" roles="*" />
<siteMapNode url="http://www.thestreet.com/_tscnav/audio/taskaudio/index.html" title="Real Story With Aaron Task" description="" roles="*" />
<siteMapNode url="http://www.thestreet.com/_tscnav/video/index.html" title="TheStreet.com TV" description="" roles="*" />
<siteMapNode url="http://online.wsj.com/public/us" title="Wall Street Journal" description="" roles="*" />
<siteMapNode url="http://www.nytimes.com/pages/business/index.html" title="New York Times Business" description="" roles="*" />
<siteMapNode url="http://markets.usatoday.com/custom/usatoday-com/html-markets.asp" title="USA Today Markets" description="" roles="*" />
<siteMapNode url="http://www.briefing.com/Investor/Public/MarketSnapshot/HeadlineHits.htm" title="Briefing.com Headline Hits" description="" roles="*" />
<siteMapNode url="http://www.pbs.org/nbr/" title="PBS Nightly Business Report" description="" roles="*" />
<siteMapNode url="http://www.redoption.com/shadow_video.php" title="RedOption Shadow Trader Video" description="Weekend Update" roles="*" />
</siteMapNode>
<siteMapNode url="~/Commentary.aspx" title="Commentary" description="" roles="*">
<siteMapNode url="http://stockmonger.blogspot.com/" title="Stock Monger" description="" roles="*" />
<siteMapNode url="http://find.thestreet.com/cgi-bin/texis/find/results.html?nh=20&amp;t=Cramer" title="Jim Cramer" description="" roles="*" />
<siteMapNode url="http://www.rightsideadvisors.com/advisors/default.aspx?" title="Richard Suttmeier" description="" roles="*" />
<siteMapNode url="http://articles.moneycentral.msn.com/Commentary/Experts/Jubak/Jim_Jubak.aspx" title="Jim Jubak" description="" roles="*" />
<siteMapNode url="http://bigpicture.typepad.com/" title="The Big Picture With Barry Ritholtz" description="" roles="*" />
</siteMapNode>
<siteMapNode url="~/Admin/Admin.aspx" title="Admin" description="" roles="Admin">
<siteMapNode url="~/Admin/UpdateAllStocks.aspx" title="Update All Stocks" description="" roles="Admin" />
<siteMapNode url="~/Admin/StockScaffold.aspx" title="Stock Scaffold" description="" roles="Admin" />
<siteMapNode url="~/Admin/ManageRoles.aspx" title="Manager User Roles" description="" roles="Admin" />
<siteMapNode url="~/Admin/ManageLists.aspx" title="Manage Lists" description="" roles="Admin" />
</siteMapNode>
</siteMapNode>
</siteMap>

Friday, July 25, 2008

Beginning Subversion (SVN) for .NET

I've had enough of zipping my project for backup before editing it. I mean it works fine for personal development, but for team projects it is time for a versioning system. That means either using CVS (Control Versioning System) or SVN (Subversion), since VSS (Visual Source Safe) would be too expensive.

First you need the download and install subversion: http://subversion.tigris.org/

Next you need to create the repository. Suppose you've created your svn directory. Fire up the command prompt and navigate there. create the "MyProject" repository:
svnadmin create MyProject

Next, recognize the recommended standard structures:
svn/MyProject
svn/MyProject/trunk
svn/MyProject/branches
svn/MyProject/tags

Next, place the trunk directory in hte MyProject directory and the .NET actual Website directory in the trunk:
svn/MyProject/trunk/MyWebsite

Next, checkout the project:
svn checkout "file:///c:/documents and settings/user/svn/MyProject"

Next, add the trunk, branches, and tags folders to the MyProject repository:
cd MyProject
svn mkdir trunk
svn mkdir branches
svn update
svn add tags

Next, commit the updates to in effect check-in the project:
svn commit -m "initial project setup"

References:
http://www.germane-software.com/~ser/R_n_R/subversion.html
http://www.onlamp.com/pub/a/bsd/2005/08/11/FreeBSD_Basics.html?page=2
http://svnbook.red-bean.com/

Saturday, July 19, 2008

Opposite Conventions List

Here is a list of opposing actions to help maintain consistent conventions:
add/remove
increment/decrement
open/close
begin/end
insert/delete
show/hide
create/destroy
lock/unlock
source/target
first/last
min/max
start/stop
get/put
next/previous
up/down
get/set
old/new
Reference: Code Complete

Saturday, July 12, 2008

Wiki Trials and Errors

I read about Wikis in Code Complete and decided to try some out for software design. This was my first contact beyond the famous Wikipedia. Wikis are basically editable html pages for documenting facts, design, and collaborating amongst users. Here are the results:

I tried FlexWiki and read their basic documentation to add namespaces and edit pages. I set it up on my localhost and continuously ran into 404 errors after updating a page. The few fixes I read about looked incomplete, so I scrapped the FlexWiki.

Next I installed DokuWiki from a PHP application on my Kensoft server. I'll update the review when I'm done setting up a sample. But in the meantime, I'd recommend avoiding FlexWiki.

Reference: http://www.splitbrain.org/go/dokuwiki

Thursday, July 3, 2008

Using a GridView with Edit and Delete that use stored procedures

Here is how to use a GridView with Edit and Delete that use stored procedures for update and delete. First, the aspx:

<asp:GridView ID="gvEmail" runat="server" AutoGenerateDeleteButton="True"
AutoGenerateEditButton="True" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
AllowPaging="True" OnRowDeleting="gvEmail_RowDeleting" PageSize="99" OnRowUpdating="gvEmail_OnRowUpdating">
<Columns>
<asp:BoundField DataField="email" HeaderText="email" SortExpression="email" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [email] FROM [vw_Email]"
DeleteCommand="sproc_DeleteEmail" DeleteCommandType="StoredProcedure"
UpdateCommand="sproc_UpdateEmail" UpdateCommandType="StoredProcedure"
>
<DeleteParameters><asp:Parameter Name="email" Type="String" /></DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="email" Type="String" />
<asp:Parameter Name="newEmail" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
Now the code behind.

protected void gvEmail_RowDeleting(object sender, GridViewDeleteEventArgs e) //DELETE
{
SqlConnection conn = new SqlConnection(SqlDataSource1.ConnectionString);
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("sproc_DeleteEmail", conn);
command.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
string email = string.Empty;
DataControlFieldCell cell = gvEmail.Rows[e.RowIndex].Cells[1] as DataControlFieldCell;
gvEmail.Columns[0].ExtractValuesFromCell(
e.Keys,
cell,
DataControlRowState.Normal,
true);
email = e.Keys[0].ToString();
if (!string.IsNullOrEmpty(email))
{
command.Parameters.AddWithValue("@email", email);
command.ExecuteNonQuery();
}
command.Parameters.Clear();
conn.Close();
}
protected void gvEmail_OnRowUpdating(object sender, GridViewUpdateEventArgs e)
{
SqlConnection conn = new SqlConnection(SqlDataSource1.ConnectionString);
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand("sproc_UpdateEmail", conn);
command.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
string newEmail = e.NewValues[0] as string;
string email = e.OldValues[0] as string;
if (!string.IsNullOrEmpty(email))
{
command.Parameters.AddWithValue("@email", email);
command.Parameters.AddWithValue("@newEmail", newEmail);
command.ExecuteNonQuery();
}
command.Parameters.Clear();
conn.Close();
}
Note: Exception handling left off for brevity.
Reference: http://www.developerfusion.co.uk/show/91/7/

Tuesday, July 1, 2008

Using XML and XPath for a GridView

This demonstrates how to use XML and XPath with a GridView to display links:

<asp:GridView ID="gvLinks" runat="server" DataSourceID="XmlDataSource1" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="Link">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" Target="_blank" NavigateUrl='<%#XPath("href") %>'>
<%#XPath("title")%>
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:Label ID="lblrOwner" runat="server" Text=&lt;%#XPath("description")%&gt;></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/App_Data/Links.xml"
XPath="links/link"></asp:XmlDataSource>
Here is the XML file:

<?xml version="1.0" encoding="utf-8" ?>
<links>
<link>
<title>Yahoo</title>
<href>http://www.yahoo.com/</href>
<owner>Yang</owner>
<description>Yahoo web portal</description>
</link>
<link>
<title>MSN</title>
<href>http://www.msn.com/</href>
<owner>Balmer</owner>
<description>Microsoft web portal</description>
</link>
<link>
<title>Delicious</title>
<href>http://del.icio.us/</href>
<owner></owner>
<description>Internet bookmark manager</description>
</link>
<link>
<title>YouTube</title>
<href>http://youtube.com/</href>
<owner></owner>
<description>Internet videos</description>
</link>
<link>
<title>SlashDot</title>
<href>http://slashdot.org/</href>
<owner></owner>
<description>News that matters</description>
</link>

</links>
Reference: http://bytes.com/forum/thread528704.html

Monday, June 23, 2008

Opening, Reading, and Writing a file

Here is an example of Opening/Reading a file in btnOpen_Click and Writing in btnSave_Click:

protected void btnOpen_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtFileName.Text)) txtFileName.Text="c:/temp/temp.txt";
StreamReader sr = null;
try
{
sr = new StreamReader(txtFileName.Text);
txtFileContent.Text = sr.ReadToEnd();
sr.Close();
displayMessage("Successfully opened file");
}
catch (Exception ex)
{
displayMessage(ex.Message);
}
finally
{
sr.Close();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtFileName.Text)) txtFileName.Text = "c:/temp/temp.txt";
StreamWriter sw = null;
try{
sw = new StreamWriter(txtFileName.Text);
string[] ar;
ar = txtFileContent.Text.Split(Environment.NewLine.ToCharArray());
foreach (string sIn in ar)
{
if(!string.IsNullOrEmpty(sIn))
sw.Write(sIn.Trim()+Environment.NewLine);
}
}catch (Exception ex)
{
displayMessageLine(ex.Message);
}
finally{
sw.Close();
}
}

Saturday, June 21, 2008

Using a nullable boolean.

It is possible to assign a nullable boolean in C#. The trick is to use ? in the declaration. Once declared, one can use the HasValue() method. An example follows:

protected void Page_Load(object sender, EventArgs e)
{
bool? isUser = null;
lblStatus.Text = isUser.HasValue.ToString(); //displays false
// an int example: Nullable<int> i = null;
}
protected void btnCheckStatus_Click(object sender, EventArgs e)
{
bool? isUser = false;
lblStatus.Text = isUser.HasValue.ToString(); //displays true
}

Thursday, June 5, 2008

Clearing controls in GridView row using delete

Here is how to clear controls in GridView row using delete. Be careful that GridViewDeleteEventArgs is not GridViewDeletedEventArgs!

<asp:GridView ID="gvStolenStatusInfo" runat="server" AutoGenerateColumns="false" AllowPaging="true"
EmptyDataText="No records found." PageSize="10" CssClass="gridView"
OnRowDeleting="gvStolenStatusInfo_RowDeleting" AutoGenerateDeleteButton="true">
<Columns>
<asp:TemplateField HeaderText="Status">
<ItemTemplate>
<asp:TextBox ID="txtuCode" runat="server" Text='<%# Bind("Code") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Comment">
<ItemTemplate>
<asp:TextBox ID="txtuComment" runat="server" Text='<%# Bind("Comment") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Notice the OnRowDeleting set to x_RowDeleting function and AutoGenerateDeleteButton. Now for the delete function:

protected void gvStolenStatusInfo_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int rowID = e.RowIndex;
((TextBox)gvStolenStatusInfo.Rows[rowID].FindControl("txtuCode")).Text = string.Empty;
((TextBox)gvStolenStatusInfo.Rows[rowID].FindControl("txtuDate")).Text = string.Empty;
}
References: http://www.codeproject.com/KB/webforms/Editable_GridView.aspx

Monday, May 5, 2008

Multiple PostBack problem with GridView

I noticed my SelectedIndexChanged method being called twice in IE7 when I selected a gridview row. I used solution 2 at http://www.codeproject.com/KB/aspnet/GVImageCommandButtonProb.aspx to solve the problem.

Resetting a StringBuilder

Here is how to reset a StringBuilder:


myStringBuilder.Length = 0;
myStringBuilder.Remove(0, myStringBuilder.Length) also works, but why bother with that one?
References: http://forums.asp.net/t/1193708.aspx

Friday, April 25, 2008

Creating a GUID from scatch

Sometimes you might want a psuedo-random string value. This can be done with:
System.Guid.NewGuid().ToString();

Saturday, April 5, 2008

Changing the default login page for use with LoginStatus control

Sometimes it is desirable to have a different default login page. For example, a simple site where administrators login at http://foo.com/admin/Login.aspx versus the standard http:foo.com/Login.aspx. The LoginStatus control will hyperlink back to the default login page. To change this default login page, change the web.config file as follows:

<authentication mode="Forms" >
<forms loginUrl="~/admin/Login.aspx"></forms>
</authentication>
Reference: http://erlend.oftedal.no/blog/?blogid=55

Wednesday, April 2, 2008

How to trim a string in javascript

How to trim a string in javascript:

var trimmed = str.replace(/^\s+|\s+$/g, '') ;
Reference: http://www.nicknettleton.com/zine/javascript/trim-a-string-in-javascript

Reading TextBox or other Control values with javascript

Reading TextBox or other Control values with javascript.
Assume TextBox ID="txtName"
First, there are the simple examples of a standard aspx page:


<script type="text/javascript" languague="javascript">
function simple1() {
var txtVal = $get('<%= txtName.ClientID %>').value;
}
function simple2() {
var txtVal = $document.getElementById('<%= txtName.ClientID %>').value;
}
</script>
Here is the complex sample used for accessing a MasterPage's updatePanel for example:

// In the ASPX class
private string scriptKey = "alertName";
private string script = "function alertName() { var txt = document.getElementById('[txtNameID]'); alert(txt.value); }";

// In the Page_Load event
script = script.Replace("[txtNameID]", txtName.ClientID);
ClientScript.RegisterClientScriptBlock(this.Page.GetType(), scriptKey, script, true);

references: http://www.velocityreviews.com/forums/t109803-callback-manager-masterpage.html

Friday, March 28, 2008

const and static declarations

const and static declarations cannot be declared together because they are always together when marked const.
Reference: http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88416.aspx

Thursday, March 27, 2008

Simulating a time spanned event with the sleep event

Here is how to simulate a time spanned event with the sleep event and a millisecond argument:

System.Threading.Thread.Sleep(2000);

Configure SQL Database for User Login

If you try and set up User Login without configuring the web.config file and try to login from a hosted site you might get an error similar to :" An attempt to attach an auto-named database for file C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\WebSites\WebSite1\App_Data\aspnetdb.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share. "
To configure it for User Login, I first added the user database to the SQL server using this method.

Next, I changed the web.config file to include:

<connectionStrings>
<add name="ConnectionString" connectionString="Data Source=my.host.net;Database=myDatabase;uid=myUserId;pwd=myPassword" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<authentication mode="Forms" />

<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalSqlServersm" requiresQuestionAndAnswer="true" requiresUniqueEmail="true" passwordFormat="Hashed" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="3" applicationName="/" enablePasswordRetrieval="false" enablePasswordReset="true" maxInvalidPasswordAttempts="3"/>
</providers>
</membership>

<roleManager enabled="true" />
Just change the myX fields to your fields. And now your configuration manager should work to add users and roles.

Monday, March 24, 2008

Running a client-side application using javascript in asp.net

Here is how to run a client-side application (.exe) using javascript in asp.net. I don't recommend it, because you probably have to lower your IE security (Tools -> Internet Options -> Security... and allow unsafe activeX).

<script language="javascript" type="text/javascript">
function btnSubmit_Click() {
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run("calc.exe");
}
</script>
<div>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClientClick="btnSubmit_Click();" />
</div>

reference: http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_11275014.html

Thursday, March 20, 2008

Setting focus in a user control

Here is how to set focus in a user control. I used it in an update panel.

ScriptManager.GetCurrent(this.Page).SetFocus(txtTarget);

Saturday, March 15, 2008

Giving Stored Procedure Permissions

To give the required permissions in SQL Server Management Express SQL 2005 database, go to Security -> Schemas. Select the target schema. Right click for properties and Add the target user to the Execute Permission.

Tuesday, March 4, 2008

Prevent wrapping in table cell

Prevent wrapping in table cell. Since the old nowrap method is out of favor, the new method is to use:


<td style="white-space:nowrap"> foo </td>

reference: http://www.thescripts.com/forum/thread468471.html
Note: this also works with a Calendar Extender and TextBox even if the cell is too short.

Sunday, March 2, 2008

Previewing a TextBox that has HTML with a Popup Window

Here is a nifty way to preview HTML in a TextBox. I use the ScriptManager and $get the TextBox ID before popping the window and then filling it.

<script type="text/javascript" language="javascript" >
function preview() {
var txt= $get('txtContent');
var sHTML= txt.value;
win = window.open(", ", 'popup', 'toolbar = no, status = no');
win.document.write("" + sHTML + "");
}
</script>
Reference: http://javascript.internet.com/forms/html-preview.html

SQL Server Management Studio Express Review

SQL Server Management Studio Express is fine GUI for manipulating your database. Unfortunately, the problems I've been having are due to the complete lack of robustness. Try copying over 500 records to your table via the cut and paste Excel method and you should expect the program to freeze up and maybe have success. I would recommend using your own stored procedure (SPROC) for data uploading tasks. It is more cumbersome, but at least it works for large data handling.

Unable to cast object of type Foo to object of type Foo

I would get the error: Unable to cast object of type Foo to object of type Foo in my dynamic control. I read some problems about that kind of error and it said to make sure the Control was set to null before the cast. No error afterwards, at least so far.

Setting up form for HTML Email and Avoiding HttpRequestValidationException

In a previous post I showed you how to set up .NET for email. But what if I want to send it as HTML. I tried and received this error: System.Web.HttpRequestValidationException: A potentially dangerous Request.Form value was detected from the client ...

The validation problem is solved by setting the Page attribute Validation="false". But then when I sent the HTML it was received as text.

The solution is to use IsHTML=true In my example, I used a check box:

protected void btnSend_Click(object sender, EventArgs e)
{
string sTo = "jane@foo.com";
string sFrom = ddlFrom.SelectedItem.Text.Trim();
string sSubject = txtSubject.Text.Trim();
string sBody = txtContent.Text.Trim();
lblStatus.Text = "Sending... please wait";
MailMessage msg = new MailMessage(sFrom, sTo, sSubject, sBody);
msg.IsBodyHtml = chkIsHTML.Checked;
SmtpClient mailObj = new SmtpClient("localHost");
mailObj.Credentials = new NetworkCredential("username", "password");
mailObj.Send(msg);
clearTexts();
lblStatus.Text = "Success: Sent message to Jane at " + DateTime.Now.ToLongTimeString() + " Eastern.";

}



References: http://www.hintsandtips.com/ShowPost/131/hat.aspx
http://aspnet.4guysfromrolla.com/articles/080206-1.aspx

Wednesday, February 27, 2008

Lazy Load Panel Courtesy of TabContainer and UpdatePanel

Here is how I implemented a Lazy load Panel. This is a nifty way to have a mini-menu of tabs without some big data transfer happening all at once. The ASP.NET render after complete model makes incremental rendering a necessary task of the developer or else the users will take a hike. This is my adaptation of Matt Burseth's example that should be helpful to avoid the LESSTHAN%= and LESSTHAN%# problems that I had. Remember to put the js in the form tag (probably below the ScriptManager). Two parts below are the ASPX and Code Behind. ASPX:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Lazy Load Panel Page</title>

</head>
<body>
<form id="form1" runat="server">
<ajax:ScriptManager ID="ScriptManager1" runat="server">
</ajax:ScriptManager>
<script type="text/javascript" language="javascript">
//var _updateProgressDiv;

function pageLoad(sender, args) {
// register for our eveents
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);

//_updateProgressDiv = $get('ActionProgress');
}
function beginRequest(sender, args) {
// get the gridview element
var tabContainer = $get('<%= this.tcTest.ClientID %>');
alert(tabContainer);
// make it visible
// _updateProgressDiv.style.display='';
}
function endRequest(sender, args) {
// make it invisible
// _updateProgressDiv.style.display='none';
}

function clientActiveTabChanged(sender, args) {
// see if table elements for the grids exist yet
var isTab1Loaded = $get('<%= this.gv1.ClientID %>');
var isTab2Loaded = $get('<%= this.gv2.ClientID %>');
var isTab3Loaded = $get('<%= this.gv3.ClientID %>');

// if tab does not exist and it is the active tab, trigger the async-postback
alert(isTab1Loaded + ',' + isTab2Loaded + ',' + isTab3Loaded + ':' + sender.get_activeTabIndex());
if (!isTab1Loaded && sender.get_activeTabIndex() == 0) {
// load tab1
// alert('fire1');
__doPostBack('<%= btn1Trigger.UniqueID %>', '');
}
if (!isTab2Loaded && sender.get_activeTabIndex() == 1 ) {
// load tab2
// alert('fire2');
__doPostBack('<%= btn2Trigger.UniqueID %>', '');
}
if (!isTab3Loaded && sender.get_activeTabIndex() == 2 ) {
// load tab3
// alert('fire3');
__doPostBack('<%= btn3Trigger.UniqueID %>', '');
}
}
</script>
<input id="btn1Trigger" runat="server" type="button" style="display:none" onserverclick="btn1Trigger_Click" />
<input id="btn2Trigger" runat="server" type="button" style="display:none" onserverclick="btn2Trigger_Click" />
<input id="btn3Trigger" runat="server" type="button" style="display:none" onserverclick="btn3Trigger_Click" />

<div>
<ajaxc:TabContainer ID="tcTest" runat="server" OnClientActiveTabChanged="clientActiveTabChanged" ActiveTabIndex="0">
<ajaxc:TabPanel ID="tp1" runat="server" HeaderText="TabPanel1">
<ContentTemplate>
<ajax:UpdatePanel ID="upnl1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
1<br />
<asp:GridView ID="gv1" runat="server" Visible="true" DataSourceID="sqlLicStatus">
</asp:GridView>
</ContentTemplate>
<Triggers>
<ajax:AsyncPostBackTrigger ControlID="btn1Trigger" />
</Triggers>
</ajax:UpdatePanel>
</ContentTemplate>
</ajaxc:TabPanel>

<ajaxc:TabPanel ID="tp2" runat="server" HeaderText="TabPanel2">
<ContentTemplate>
<ajax:UpdatePanel ID="upnl2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
2<br />
<asp:GridView ID="gv2" runat="server" Visible="False" DataSourceID="sqlCondition" >
</asp:GridView>
</ContentTemplate>
<Triggers>
<ajax:AsyncPostBackTrigger ControlID="btn2Trigger" />
</Triggers>
</ajax:UpdatePanel>
</ContentTemplate>
</ajaxc:TabPanel>

<ajaxc:TabPanel ID="tp3" runat="server" HeaderText="TabPanel3">
<ContentTemplate>
<ajax:UpdatePanel ID="upnl3" runat="server" UpdateMode="Conditional">
<ContentTemplate>
3<br />
<asp:GridView ID="gv3" runat="server" Visible="False" DataSourceID="sqlCondition" >
</asp:GridView>
</ContentTemplate>
<Triggers>
<ajax:AsyncPostBackTrigger ControlID="btn3Trigger" />
</Triggers>
</ajax:UpdatePanel>
</ContentTemplate>
</ajaxc:TabPanel>

</ajaxc:TabContainer>
</div>





<asp:SqlDataSource ID="sqlLicStatus" runat="server"
ProviderName="System.Data.Bar"
DataSourceMode="DataReader"
ConnectionString="foo"
SelectCommand="SELECT foo FROM Validations WHERE bar=102 ORDER BY Code;">
</asp:SqlDataSource>
<asp:SqlDataSource ID="sqlCondition" runat="server"
ProviderName="System.Data.Foo"
DataSourceMode="DataReader"
ConnectionString="foo"
SelectCommand="SELECT foo FROM Validations WHERE bar=18 ORDER BY Code;">
</asp:SqlDataSource>
</form>
</body>
</html>
Code Behind:

/// <summary>
/// Lazy load TabPanel in a TabContainer
/// The update panel contents are fetched if client trigger is fired.
/// The client trigger is fired if the target tab is active and the
/// target GridView is not active (visible).
/// </summary>
public partial class Samples_LazyPanel : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void btn1Trigger_Click(object sender, EventArgs args)
{
this.gv1.Visible = true;
this.gv1.DataBind();
}
protected void btn2Trigger_Click(object sender, EventArgs args)
{
this.gv2.Visible = true;
this.gv2.DataBind();
}
protected void btn3Trigger_Click(object sender, EventArgs args)
{
this.gv3.Visible = true;
this.gv3.DataBind();
}
}

Blog Archive