Monday, June 30, 2008

How to sort and allow paging manually using Gridview

private string ConvertSortDirectionToSql(SortDirection sortDirection)
{
string newSortDirection = String.Empty;

switch (sortDirection)
{
case SortDirection.Ascending:
newSortDirection = "ASC";
break;

case SortDirection.Descending:
newSortDirection = "DESC";
break;
}

return newSortDirection;
}

protected void gridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gridView.PageIndex = e.NewPageIndex;
gridView.DataBind();
}

protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
{
DataTable dataTable = gridView.DataSource as DataTable;

if (dataTable != null)
{
DataView dataView = new DataView(dataTable);
dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);

gridView.DataSource = dataView;
gridView.DataBind();
}
}

Thursday, June 26, 2008

How to have a pop out dialog box in ASP.NET

JHaIn all good web applications, the user is asked to confirm whether he/she wants to delete something in case the delete button was pressed accidentally.

Although it seems like a pain to do, it is actually really easy if you find it acceptable to use javascript's “confirm” statement, which will popup a dialog box with a particular question with “ok” and “cancel” buttons. You have no control of the title of the popup, but in IE it says “Microsoft Internet Explorer“ and I believe it says “[Javascript Application]“ or similar in Firebird.





The javascript code for it is simple:


function confirm_delete()
{
if (confirm("Are you sure you want to delete the custom search?")==true)
return true;
else
return false;
}


Using code-behind, you can attach the javascript popup dialog to the button:


_myButton.Attributes.Add("onclick", "return confirm_delete();");

When you click on the delete button, the javascript popup dialog asks if you want to delete the search. If you choose “cancel“, your “DeleteSearch_Click” event is never fired. If you choose “ok”, the event is fired and you can delete the item.

How to Select a Row in GridView without using select button


....
....
....


protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs
e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onclick",
ClientScript.GetPostBackEventReference(MyGridView, "Select$" +
e.Row.RowIndex.ToString()));
e.Row.Style.Add("cursor", "pointer");
}
}

protected void MyGridView_SelectedIndexChanged(object sender, EventArgs e)
{
string strSelectedID = MyGridView.SelectedValue.ToString();
}

Wednesday, June 18, 2008

How to Authenticate User using a customed Database

If you want to authenticate a user against your own custom database then you can use the Authenticate event of the Login control. Here is a small example that shows how to achieve it.

// Use Authenticate event if you want to do custom authentication

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)

{

string userName = Login1.UserName;

string password = Login1.Password;

bool result = UserLogin(userName, password);

if (result)

e.Authenticated = true;

else

e.Authenticated = false;

}

private bool UserLogin(string userName, string password)

{

string query = @"SELECT UserName FROM Users WHERE

UserName = @UserName AND Password = @Password";

string connectionString = (string)ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

SqlConnection myConnection = new SqlConnection(connectionString);

SqlCommand myCommand = new SqlCommand(query, myConnection);

myCommand.Parameters.AddWithValue("@UserName", userName);

myCommand.Parameters.AddWithValue("@Password", password);

myConnection.Open();

string userId = (string) myCommand.ExecuteScalar();

myConnection.Close();

if (userId != null && userId.Length > 0)

return true;

else return false;

}

As you can see that I am simply sending the values from the Login control to UserLogin method and returns true or false based on the authentication status.

When using custom authentication always remember to set the Authenticated property of the Login control to true or false based on the result of authentication. Also when authenticating a user against a custom database you don't need to provide the membership settings in the web.config file.

How to use CheckBox in GridView.

Introduction

In the preceding tutorial we examined how to add a column of radio buttons to the GridView for the purpose of selecting a particular record. A column of radio buttons is a suitable user interface when the user is limited to choosing at most one item from the grid. At times, however, we may want to allow the user to pick an arbitrary number of items from the grid. Web-based email clients, for example, typically display the list of messages with a column of checkboxes. The user can select an arbitrary number of messages and then perform some action, such as moving the emails to another folder or deleting them.

In this tutorial we will see how to add a column of checkboxes and how to determine what checkboxes were checked on postback. In particular, we’ll build an example that closely mimics the web-based email client user interface. Our example will include a paged GridView listing the products in the Products database table with a checkbox in each row (see Figure 1). A “Delete Selected Products” button, when clicked, will delete those products selected.

Each Product Row Includes a Checkbox

Figure 1: Each Product Row Includes a Checkbox (Click to view full-size image)

Step 1: Adding a Paged GridView that Lists Product Information

Before we worry about adding a column of checkboxes, let’s first focus on listing the products in a GridView that supports paging. Start by opening the CheckBoxField.aspx page in the EnhancedGridView folder and drag a GridView from the Toolbox onto the Designer, setting its ID to Products. Next, choose to bind the GridView to a new ObjectDataSource named ProductsDataSource. Configure the ObjectDataSource to use the ProductsBLL class, calling the GetProducts() method to return the data. Since this GridView will be read-only, set the drop-down lists in the UPDATE, INSERT, and DELETE tabs to “(None)”.

Create a New ObjectDataSource Named ProductsDataSource

Figure 2: Create a New ObjectDataSource Named ProductsDataSource (Click to view full-size image)

Configure the ObjectDataSource to Retrieve Data Using the GetProducts() Method

Figure 3: Configure the ObjectDataSource to Retrieve Data Using the GetProducts() Method (Click to view full-size image)

Set the Drop-Down Lists in the UPDATE, INSERT, and DELETE Tabs to “(None)”

Figure 4: Set the Drop-Down Lists in the UPDATE, INSERT, and DELETE Tabs to “(None)” (Click to view full-size image)

After completing the Configure Data Source wizard, Visual Studio will automatically create BoundColumns and a CheckBoxColumn for the product-related data fields. Like we did in the previous tutorial, remove all but the ProductName, CategoryName, and UnitPrice BoundFields, and change the HeaderText properties to “Product”, “Category”, and “Price”. Configure the UnitPrice BoundField so that its value is formatted as a currency. Also configure the GridView to support paging by checking the “Enable Paging” checkbox from the smart tag.

Let’s also add the user interface for deleting the selected products. Add a Button Web control beneath the GridView, setting its ID to DeleteSelectedProducts and its Text property to “Delete Selected Products”. Rather than actually deleting products from the database, for this example we’ll just display a message stating the products that would have been deleted. To accommodate this, add a Label Web control beneath the Button. Set its ID to DeleteResults, clear out its Text property, and set its Visible and EnableViewState properties to False.

g="{0:c}" HeaderText="Price" HtmlEncode="False" SortExpression="UnitP

T
ake a moment to view the page in a browser (see Figure 5). At this point you should see the name, category, and price of the first ten products.
The Name, Category, and Price of the First Ten Products are Listed

Figure 5: The Name, Category, and Price of the First Ten Products are Listed (Click to view full-size image)

Step 2: Adding a Column of Checkboxes

Since ASP.NET 2.0 includes a CheckBoxField, one might think that it could be used to add a column of checkboxes to a GridView. Unfortunately, that is not the case, as the CheckBoxField is designed to work with a Boolean data field. That is, in order to use the CheckBoxField we must specify the underlying data field whose value is consulted to determine whether the rendered checkbox is checked. We cannot use the CheckBoxField to just include a column of unchecked checkboxes.

Instead, we must add a TemplateField and add a CheckBox Web control to its ItemTemplate. Go ahead and add a TemplateField to the Products GridView and make it the first (far-left) field. From the GridView’s smart tag, click on the “Edit Templates” link and then drag a CheckBox Web control from the Toolbox into the ItemTemplate. Set this CheckBox’s ID property to ProductSelector.

Add a CheckBox Web Control Named ProductSelector to the TemplateField’s ItemTemplate

Figure 6: Add a CheckBox Web Control Named ProductSelector to the TemplateField’s ItemTemplate (Click to view full-size image)

With the TemplateField and CheckBox Web control added, each row now includes a checkbox. Figure 7 shows this page, when viewed through a browser, after the TemplateField and CheckBox have been added.

Each Product Row Now Includes a Checkbox

Figure 7: Each Product Row Now Includes a Checkbox (Click to view full-size image)

Step 3: Determining What Checkboxes Were Checked On Postback

At this point we have a column of checkboxes but no way to determine what checkboxes were checked on postback. When the “Delete Selected Products” button is clicked, though, we need to know what checkboxes were checked in order to delete those products.

The GridView’s Rows property provides access to the data rows in the GridView. We can iterate through these rows, programmatically access the CheckBox control, and then consult its Checked property to determine whether the CheckBox has been selected.

Create an event handler for the DeleteSelectedProducts Button Web control’s Click event and add the following code:

Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _ Handles DeleteSelectedProducts.Click

Dim atLeastOneRowDeleted As Boolean = False
' Iterate through the Products.Rows property For Each row As GridViewRow In Products.Rows
' Access the CheckBox Dim cb As CheckBox = row.FindControl("ProductSelector")
If cb IsNot Nothing AndAlso cb.Checked Then
' Delete row! (Well, not really...)
atLeastOneRowDeleted = True
' First, get the ProductID for the selected row
Dim productID As Integer = _ Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
' "Delete" the row DeleteResults.Text &= String.Format( _ "This would have deleted ProductID {0}
", productID)

The Rows property returns a collection of GridViewRow instances that makeup the GridView’s data rows. The For Each loop here enumerates this collection. For each GridViewRow object, the row’s CheckBox is programmatically accessed using row.FindControl("controlID"). If the CheckBox is checked, the row’s corresponding ProductID value is retrieved from the DataKeys collection. In this exercise, we simply display an informative message in the DeleteResults Label, although in a working application we’d instead make a call to the ProductsBLL class’s DeleteProduct(productID) method.

With the addition of this event handler, clicking the “Delete Selected Products” button now displays the ProductIDs of the selected products.

When the “Delete Selected Products” Button is Clicked the Selected Products’ ProductIDs are Listed

Figure 8: When the “Delete Selected Products” Button is Clicked the Selected Products’ ProductIDs are Listed (Click to view full-size image)

Step 4: Adding “Check All” and “Uncheck All” Buttons

If a user wants to delete all products on the current page, they must check each of the ten checkboxes. We can help expedite this process by adding a “Check All” button that, when clicked, selects all of the checkboxes in the grid. An “Uncheck All” button would be equally helpful.

Add two Button Web controls to the page, placing them above the GridView. Set the first one’s ID to CheckAll and its Text property to “Check All”; set the second one’s ID to UncheckAll and its Text property to “Uncheck All”.

Next, create a method in the code-behind class named ToggleCheckState(checkState) that, when invoked, enumerates the Products GridView’s Rows collection and sets each CheckBox’s Checked property to the value of the passed in checkState parameter.

Private Sub ToggleCheckState(ByVal checkState As Boolean) ' Iterate through the Products.Rows property For Each row As GridViewRow In Products.Rows ' Access the CheckBox Dim cb As CheckBox = row.FindControl("ProductSelector") If cb IsNot Nothing Then cb.Checked = checkState End If Next End Sub

Next, create Click event handlers for the CheckAll and UncheckAll buttons. In CheckAll’s event handler, simply call ToggleCheckState(True); in UncheckAll, call ToggleCheckState(False).

Protected Sub CheckAll_Click(sender As Object, e As EventArgs) _ Handles CheckAll.Click ToggleCheckState(True) End Sub Protected Sub UncheckAll_Click(sender As Object, e As EventArgs) _ Handles UncheckAll.Click ToggleCheckState(False) End Sub

With this code, clicking the “Check All” button causes a postback and checks all of the checkboxes in the GridView. Likewise, clicking “Uncheck All” unselects all checkboxes. Figure 9 shows the screen after the “Check All” button has been checked.

Clicking the “Check All” Button Selects All Checkboxes

Figure 9: Clicking the “Check All” Button Selects All Checkboxes (Click to view full-size image)

Note: When displaying a column of checkboxes, one approach for selecting or unselecting all of the checkboxes is through a checkbox in the header row. Moreover, the current “Check All” / “Uncheck All” implementation requires a postback. The checkboxes can be checked or unchecked, however, entirely through client-side script, thereby providing a snappier user experience. To explore using a header row checkbox for “Check All” and “Uncheck All” in detail, along with a discussion on using client-side techniques, check out Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox.

Summary

In cases where you need to let users choose an arbitrary number of rows from a GridView before proceeding, adding a column of checkboxes is one option. As we saw in this tutorial, including a column of checkboxes in the GridView entails adding a TemplateField with a CheckBox Web control. By using a Web control (versus injecting markup directly into the template, as we did in the previous tutorial) ASP.NET automatically remembers what CheckBoxes were and were not checked across postback. We can also programmatically access the CheckBoxes in code to determine whether a given CheckBox is checked, or to chnage the checked state.

This tutorial and the last one looked at adding a row selector column to the GridView. In our next tutorial we’ll examine how, with a bit of work, we can add inserting capabilities to the GridView.


Wednesday, June 11, 2008

Method Error 500

I've been assigned a bug concerning an AJAX cascading drop down combo box. When the Ajax cascading drop down combo box's value is changed by the user, a secondary combo box has its values reloaded. This is done by calling a web service. The bug is that "Method Error 500" is displayed as the only item on occasion.

After some rooting around, it turns out that this is caused by too much data being returned in the SQL query behind the web service call, so the web service returns an error. A simple change to the web.config file can increase the size limit of data returned:

<system.web.extensions>
<scripting>
<webservices>
<jsonserialization maxjsonlength="5000000">
</jsonserialization>
</webservices>
</scripting>
<system.web.extensions>
<scripting>
<webservices>
<jsonserialization maxjsonlength="5000000">
</jsonserialization>
</webservices>
</scripting>
</system.web.extensions></system.web.extensions>

Sunday, June 08, 2008

How Do I Make an Out of Office AutoResponder If I Use Outlook Without Exchange Server?



This is a question I get asked a lot. If you have Outlook at work Exchange Server), you are used to the Out of Office Assistant which is easy to use to set up a reply to all of your mail when you are away from the office. But, without Exchange Server, this option is not available to you in your Tools menu, so you have to create a rule that will reply to all using a template.

NOTE: In order for this to work correctly, DO NOT use Word as your email editor and use PLAIN TEXT as your mail format.



First: How To Make the Template

Open a new blank email and write your message with any info you want included. For example:

Hi. I'm out of town for three days. If you want to reach me, you can email me at joeblow@duhhh.com. Otherwise, I will reply to you when I return on Dec. 15, 2002.

Sincerely,
Eugene

Once you are done setting up the message, click on the File menu within the email and choose "Save As". When the Save As box comes up, use the menu at the bottom that says "Save as type" and choose Outlook Template (*.oft).

Notice when you choose to save it as a template, at the top of the Save As box, where it says "Save In", it now shows that it is saving it in your Templates folder. DO NOT CHANGE THIS LOCATION. It needs to be there so you can select it from your Templates library.

Give the template a name and click the Save button. Now you can just close this mail by clicking on the X in its upper right corner. (Say No when Outlook asks if you want to save the mail. Since we have already saved the Template, there is no need to save the actual email.)



Second: How To Make the Rule So It AutoReplies To Everyone

Go to your Tools menu in Outlook and select Rules Wizard. Click on "New" to start the Wizard. In the first step where it asks what conditions you want to set for this rule, just leave everything unchecked and click on Next and Outlook will give you a message that tells you this rule will be applied to all mail you receive. Click Yes. The first step of the Rules Wizard asks if you want to base this rule on an existing rule or start with a new rule. Tell it to start with a new blank rule.)

The next step asks what you want to do with the mail. Look through the list of choices and check the one that says "Reply with a specific template". Now you will see the words "a specific template" in the bottom pane. Click on the underlined words and use the dropdown box at the top of the box you now see to select "User Templates in File System" and you will see your template. Select it and click on Open. Now you will see that your rule is setup to reply to everyone with this template.

If you want to setup any exceptions for this rule, you can click Next. Otherwise, just click on Finish and your rule is made and turned on.

Now, if you don't want the rule to run now, but instead, want it to start running tomorrow or some other time, just go back to Tools>Rules Wizard and find your rule and uncheck the box beside it. Then, you can just return here before you go away to turn the rule on by checking it again. When you return home, remember to go back here and uncheck it again to turn it off, or click on it to select it and click on the button that says Delete to remove it completely.

Thursday, June 05, 2008

Microsoft Heroes Happen here event


Microsoft has launch the new windows server 2008, Visual Studio 2008 and SQL server 2008. And as a developer, I am impacted by the changes in these technologies.

Unfortunately, Microsoft learning is way behind in the times, and the new string of certifications does not come out until August 2008. This means that I need to learn everything quickly on my own again. time to sign up with either Comat or New Horizons to upgrade my skills and certifications. The CITREP offered by IDA offers a 50% subsidy for courses capped at $3000 making upgrading my certifications very attractive.

New Horizons seems to get my vote, as they offer PMP, Oracle, Lotus, Security and JAVA as well in addition to .NET.

Comat is a close competitor, with PMP and N+ and .NET.

The problem is these courses are crazy and insanely expensive. :P This is the only thing stopping me from training and upgrading my certifications.

Thursday, February 08, 2007

The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID

You may see this error - more than once - when working with your Microsoft Office SharePoint Server (MOSS) 2007 deployment. This animal / error generally shows itself after you have applied an upgrade to an existing deployment. For example, when upgrading from B2 MOSS to B2TR MOSS - or when applying a special service pack from MSFT - you may begin to see a lot of these errors pop up in the SYSTEM event log.

The error CLSID is followed by a class ID for the DCOM+ application that the service account trying to activate that application - does NOT have permission to activate.

For example, let's say I installed MOSS on a server, and used the account mossService as the service account (a least privileged, user account you created to run the MOSS service(s))., when I get this error, I could very well see an error like the following:

The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID
{61738644-F196-11D0-9953-00C04FD919C1}
to the user \mossService SID (S-1-5-21-). This security permission can be modified using the Component Services administrative tool.

  • Copy the GUID following the CLSID above, and Start-->Run-->regedit
  • With the registry editor open, ensure that your cursor is on the computer at the beginning of the tree (make sure you are not in the middle of some previous edit session in the registry editor).
  • Edit-->Find and paste in the GUID. It'll stop at the application entry - and you will want to note the application name on the right side pane. In this example, it was the IIS WAMREG admin service that popped up.
  • Now, open Component Services (typically, from the server - Start-->Administrative Tools-->Component Services), expand Component Services, Computers, My Computer, DCOM Config. Scroll down and find the application (IIS WAMREG in this case).
  • Right-Click-->Properties and select the Security tab. You'll have some options here - the first block Launch and Activation Permissions - ensure that the Customize radio button is selected, and click Edit. Now, add your service account - giving it launch and activate - and in some requirements - remote launch / activate permission.
  • Restart IIS and continue on.

Wednesday, December 06, 2006

Jython Quick References

Table 1. Summary of Jython data types

TypeComment Example
NullAn undefined value (like null in the Java language).None
IntegerA normal (int in the Java language) or long (BigInteger in the Java language) integer number.
-1  0  100
-1L 1000000000000000000000000000000000000000000001L

Float A fractional or exponential (like double in the Java language) number.
1.0
-1e6 0.000001e-10 1E11

Complex A pair of floats supporting complex arithmetic.
1j  -10J
2-3j 1e6j

String An immutable sequence of characters. There is no character type (use one character strings instead).
"a string"
'a string'
"""a long (possibly multi-line) string"""
'''another (possibly multi-line) long string'''
r'''^xxx(.*?)\.yyy(.*?)\.zzz(.*?)\.$'''
'x' "y" '\n' "\\"

Range An immutable sequence of integers.
range(10)
range(10,0,-1)
xrange(1,100000,10)

Tuple An immutable sequence of any type (like java.util.Collections.unmodifiableCollection(someList)).
()  (1,)  (1,2,3)
(1, "mixed", 2, "tuple")
((1,2),(3,4))

List A mutable sequence of any type (like java.util.ArrayList).
[]  [1]  [1,2,3]
[1, 'mixed', 2, 'list']
[[1,2],[3,4]]

Map A mutable collection of items (name/value pairs) (like java.util.Map). Names must be immutable and unique; values may be None.
{}
{1:'one',2:'two',3:'three'}
{"one";1, "two":2, "three":3}
{"x":1, "ints":(1,2,3),
"name":{"first":"Barry", last":"Feigenbaum"}}

Boolean A true/false value based on other types. false - 0 or empty:
None
0 0.0
() []


true - non-0, not empty:
1  -1  0.0001
[1] [1,2,3] {"greeting":"Hello!"}

Function Any function. Functions do not need to be members of classes.
lambda x: x > 0

def isPositive(x): return x > 0

def addem(x,y,z):
return x + y + z

Class Any class. Classes are namespaces for class attributes and functions (called methods).
class MyClass:
x = 1
y = 2

class subclass(superClass):
def method1(self): ...

def method2(self, arg1, arg2): ...

Module A source file (and namespace) that contains variable, function and/or class definitions. Any .py file that defines importable variables, functions and/or classes. If it does not define any of these then it is just called a script.


Back to top


Statement types

Jython provides the statement types summarized in Table 2.

Table 2. Summary of Jython statement types

Statement Comment Examples
Expression Any expression. The results are discarded. Often used for their side effects.
(1 * 2) ** 3 / 4

"string"[2:] == "ring"

someFunction(1, 2, 3)

Assignment Assigns an expression to a target.
x = 3
x = f(1,32,3) * 10 + x

list[1:3] = [7, 8, 9 , 10]

Augmented Assignment Updates a target with an expression.
x *= 100

s += "…"

Unpacking Assignment Assigns elements of a sequence to multiple targets; very convenient for access to tuple and list members. Note that the expression 1,2,3 is a short form of (1,2,3).
x,y,z = 1,2,3

Multiple Assignment Assigns the same expression to multiple targets.
z = y = z = 10

Pass No operation.
pass

If
If/Else
If/Elif/Else
Conditional processing.
if x < 0: x = -x

if x == 3:
print "It's three!"

if x == 1: ...
elif x == 2: ...
elif x == 3: ...
else: print "Bad value " + x

While Looping over a condition.
x = 10
while x > 0:
print x
x -= 1

For Iterates over a sequence. Use range to iterate over a numeric sequence.
for i in range(10): print i

for c in "A string":
print c

for i in (10, "Hello", 1e6):
print func(i)

Continue Advances to the next loop (while/for) iteration.
for i in range(10):
if not testOk(i):
continue
:

Break Exits a loop (while/for)
for i in range(10):
if testBad(i):
break
:

Delete Removes a variable or sequence element(s) or class attribute.
del x

del list[3:5]

del x.attr1

Global Declares a reference to a global value; used in functions.
x,y,z = 0,1,2
def f(a,b,c):
global x,y,z
:

Print Prints expression(s) to a stream.
print "Hello World!"
print "Hello","World!"
print "Hello" + ' ' + "World!"

msg = "Name: %(last)s, (first)s"
data = {'last':"Feigenbaum", 'first':"Barry"}
print >>out, msg % data

Assert Asserts a condition is true.
def process(v):
assert v > 0, "Illegal value %i" % v
:

Import Imports all or part of a module.
import sys
from sys import argv
from javax import swing
from java.util import Map

Execute Executes a string/file as a subprogram. There is also a related function, exec, that executes a constructed string and returns its result. This support allows you to dynamically create programs.
globals = {'x':1, 'y':2, 'z':3}
locals = {'list':(1,2,3)}
code = "print x, y, z, list"
exec code in globals, locals

Try/Except Executes code within an exception handler.
try:
x = int(string)
except ValueError, e:
x = 0

Try/Finally Executes code with a cleanup routine.
f = open("test.dat")
try:
lines = f.readlines()
finally:
f.close()

Raise Creates and throws an exception.
def factorial(x):
raise ValueError, "x must be > 0"
:

Define Defines a function; arguments may be optional and/or keywords; Functions are generic which allows for very flexible programming.
def f(x,y=2,z=10): return x+y+z

q = f(1,2) + f(3) + f(4,5,6)
s = f("a","b","c")

Return Returns from a function with an optional value.
return 10

Class Defines a class (a container for attributes and methods) .
class X: pass

class MyClass(SomeClass):
pass



Back to top

Tuesday, November 28, 2006

Reading and Editing Registry Keys

First, you need to import Microsoft.win32.

Sample code for edit the registry

Public Shared Sub UpdateiPhysicalFlagTo0()
Dim regConnectionKey As RegistryKey
regConnectionKey = Registry.LocalMachine.OpenSubKey("key here", True)
If (regConnectionKey Is Nothing) Then
regConnectionKey.Close()
Else
Try
regConnectionKey.SetValue("FirstTimeTrain", "0")
regConnectionKey.Close()
Catch er As Exception
Throw New Exception(er.Message)
End Try
End If
End Sub

Sample code for reading registry

Public Shared Function GetRegistryFirstTimeTraining() As Boolean
Dim bool As Boolean = False
Dim regConnectionKey As RegistryKey
regConnectionKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\SQLView\\DMSConnection")
If (regConnectionKey Is Nothing) Then
Throw New Exception("GetRegistryFirstTimeTraining() : The registry key is not found")
Else
Try
Dim vr As String
vr = regConnectionKey.GetValue("FirstTimeTrain")
regConnectionKey.Close()
If (vr.ToString() = "1") Then
bool = True
End If
Return bool
Catch er As Exception
Throw New Exception(er.Message)
End Try
End If
End Function

Thursday, November 23, 2006

IDIOTIC Me Missing Dlls

When an application I was developing failed to work in the deployment area, I struggled hard to find the bug, and the clause of the problem.

Like most novice programmers, I concentrated on the code, twinking here and there, trying to get it working. But tried as I might, I could not find the clause of the problem. Finally I could not bear it any longer, approached my supervisor for help to trace the problem.

My supervisor, Sindy, is a smart lady, who immediately look at the dll.. And discovered that one dll is missing from the deployment package. When she inserted the missing dll, the whole thing work well.

Lesson Learnt and Humble pie eaten: Always check the dll when you are deploying to a the deployment area to make sure no missing dll. This save you a lot of time in the long run. Missing dlls are very hard to trace and problematic.

Sunday, November 19, 2006

Oracle and Autonumber



Oracle does not have an autonumber like SQLServer has. Oracle's way to for autonumbers is using sequences and triggers. The sequence makes sure that unique numbers are generated while the trigger fills the these numbers into the column for which an autonumber is desired. This is demonstrated in the following.
I need a table with a autonumber column. In this case, it will be column id.
create table tbl_autonumber(
id number primary key,
txt varchar2(20)
);
Then, the sequence:
create sequence seq_autonumber;
And the trigger. It fires whenever a new record is inserted and assigns the sequence's next value (using nextval) to :new.id.
create trigger trg_autonumber
before insert on tbl_autonumber
for each row
begin
select seq_autonumber.nextval into :new.id from dual;
end;
/
Now, three records are inserted:
insert into tbl_autonumber (txt) values('bar');
insert into tbl_autonumber (txt) values('baz');
insert into tbl_autonumber (txt) values('qqq');
select * from tbl_autonumber;
The trigger did its job and filled id with unique values:
        ID TXT
1 bar
2 baz
3 qqq
Now, trying to circumvent the 'autonumber' and specify an aribtrary id:
insert into tbl_autonumber (id, txt) values(100, '###');
insert into tbl_autonumber (id, txt) values(200, '???');
insert into tbl_autonumber (id, txt) values(300, '!!!');
Doesn't work, is overwritten by trigger!
select * from tbl_autonumber;
        ID TXT
---------- -------------------------
1 bar
2 baz
3 qqq
4 ###
5 ???
6 !!!
Changing the trigger and ...
create or replace trigger trg_autonumber
before insert on tbl_autonumber
for each row
begin
if :new.id is null then
select seq_autonumber.nextval into :new.id from dual;
end if;
end;
/
.... trying again to overrule the trigger:
insert into tbl_autonumber (id, txt) values(111, 'This');
insert into tbl_autonumber (id, txt) values(222, 'should');
insert into tbl_autonumber (id, txt) values(333, 'work');
And indeed, it worked. However....
select * from tbl_autonumber;
        ID TXT
---------- --------------------------------------
1 bar
2 baz
3 qqq
4 ###
5 ???
6 !!!
111 This
222 should
333 work
.... it should be clear that it is a bad idea to supply primary keys if there is a sequence.

Thursday, October 19, 2006

How to custom define ApplicationExit Event

In the main() method, before calling the application.Start.Run() or Application.Run() methods,
include the following line of code

AddHandler Application.ApplicationExit, AddressOf OnApplicationExit

Include another method in the application as follows

VB:
Private Sub OnApplicationExit(ByVal sender As Object, ByVal e As EventArgs)
'your code here.
End Sub
C#:
private void OnApplicationExit(object sender, EventArgs e) {
// Your code here.
}

Tuesday, September 19, 2006

Could not load file or assembly 'CrystalDecisions.CrystalReports'

I managed to get hold of Visual Studio 2005, and like any new programmers, I was rubbing my hands in glee at getting the latest toolkit for development.

When I tried to open an existing file in Visual Studio 2005, it prompted me to upgrade to the .NET framework and create a new webconfig file. Then my nightmare with debugging begins, especially with Crystal Reports. In particular, this error got me stumped

Could not load file or assembly 'CrystalDecisions.CrystalReports.Engine visual studio 2005 .

The error occurs in the web.config file.

add assembly="CrystalDecisions.CrystalReports.Engine, Version=10.2.3000.0, Culture=neutral, PublicKeyToken="

I tried everything I knew, googling it, getting deployment packages from BusinessObjects etc. But none of them work as all I want is to compile my code without the darn error and make sure the migration to .NET 2.0 is successful.

So after sitting in the dark without a clue to what the error may be for an hour and fed up with reading tons of articles that don't work, I decided I have enough of googling and time to do something. As a first step, I open the bin folder, and check the Crystall report dll. Oops! There is the darn error! The version number for the old dll is 9.1.9800.9 and the assembly version is 10.2.3000.0! So I delete all the dll, and add the new CrystalReport dll.

To my surprise, Visual Studio version number is higher than what the assembly version is 10.2.5150.0. Thinking myself smart, I did what I think is right and changed the assembly in the web.config file to

add assembly="CrystalDecisions.CrystalReports.Engine, Version=10.2.5150.0, Culture=neutral, PublicKeyToken="

Then I found out that there is no such assembly in the .NET 2.0. Only the Version 10.2.3000.0 is there in the assembly. All attempts to add the new version into the assembly failed. Since I cannot edit the assembly, I tried changing it back the original version:

add assembly="CrystalDecisions.CrystalReports.Engine, Version=10.2.3000.0, Culture=neutral, PublicKeyToken="

And hey pesto, everything suddenly can compile!

Morale of story: Make sure your dlls in the bin directory in your new .NET 2.0 application is updated to the latest version and leave the assembly code in the web.config file alone. It saves you a lot of pain in migrating to .NET 2.0.

Sunday, September 03, 2006

How to send Email using C#

In order to send email in C# in ASP.NET 1.1., do the following:
using System.Web.Mail;

// create mail message object
MailMessage mail = new MailMessage();
mail.From = ""; // put the from address here
mail.To = ""; // put to address here
mail.Subject = ""; // put subject here
mail.Body = ""; // put body of email here
SmtpMail.SmtpServer = ""; // put smtp server you will use here
// and then send the mail
SmtpMail.Send(mail);


In ASP.NET 2.0, the MailMessage class and Smtp.Mail is obsoleted. Instead, you have to use the following code:

public static void CreateTestMessage4(string server)
{
MailAddress from = new MailAddress("ben@contoso.com");
MailAddress to = new MailAddress("Jane@contoso.com");
MailMessage message = new MailMessage(from, to);
message.Subject = "Using the SmtpClient class.";
message.Body = @"Using this feature, you can send an e-mail message from an application very easily.";
SmtpClient client = new SmtpClient(server);
Console.WriteLine("Sending an e-mail message to {0} by using SMTP host {1} port {2}.",
to.ToString(), client.Host, client.Port);
client.Send(message);
}




Monday, July 24, 2006

How to store the database connection in webconfig file in ASP.NET

ASP.NET provides a configuration system we can use to keep our applications flexible at runtime. In this article we will examine some tips and best practices for using the configuration system for the best results.

The element of a web.config file is a place to store connection strings, server names, file paths, and other miscellaneous settings needed by an application to perform work. The items inside appSettings are items that need to be configurable depending upon the environment, for instance, any database connection strings will change as you move your application from a testing and staging server into production.

As an example, let’s examine this appSetting entry in the web.config file to hold our connection string:

<appsettings>
<add key="ConnectionInfo" value="Data Source=Annapurna;Initial Catalog=ISClass;User Id=isclass;Password=isclass">
<appsettings>


To read the key we use the ConfigurationSettings class from the System.Configuration namespace, as shown below.

12 private void Page_Load(object sender, EventArgs e)

13 {

14 string connectionInfo = ConfigurationSettings.AppSettings["ConnectionInfo"];

15 using(SqlConnection connection = new SqlConnection(connectionInfo))

16 {

17 connection.Open();

18

19 // perform work with connection

20

21 }

22 }

Some applications will duplicate these lines of code in many places. If we think about how the above code will evolve over time, we might see a handful of weaknesses. First, we have a hard coded string in place to fetch connection information from the web.config. Hard coded strings can be easy to mistype and difficult to track down if the key ever changes. Secondly, the code will tie us forever to the appSettings section of the web.config file. Although web.config is designed for just such a setting, we might find in the future that we need to pull configuration settings from a database, or change a setting from being application-wide to being a per-user configuration item kept in the Session or in a cookie.

Encapsulation

Let’s abstract away the source of the connection string using a class with a static property.

1 using System.Configuration;

2

3 namespace aspnet.config

4 {

5 public class Configuration

6 {

7 public static string ConnectionInfo

8 {

9 get

10 {

11 return ConfigurationSettings.AppSettings["ConnectionInfo"];

12 }

13

14 }

15 }

16 }

Now our Page_Load method looks like the following.

11 private void Page_Load(object sender, EventArgs e)

12 {

13 using(SqlConnection connection = new SqlConnection(Configuration.ConnectionInfo))

14 {

15 connection.Open();

16

17 // perform work with connection

18

19 }

20 }

The changes we made to the above code were relatively small - but powerful. Now the Page_Load function doesn’t know where the connection string comes from. We could easily change the ConnectionInfo property to retrieve the string from a different source without modifying any other code in the application. We also no longer have to remember the key string and hard code the string at various points in the application. Instead, we can utilize Visual Studio Intellisense when accessing the Configuration class to find the setting we need. The key value only appears once – inside the ConnectionInfo property – so we could again change the key name in the web.config and have only one line of code to update.

Of course this approach only works if all of the code in the application goes to the Configuration class instead of directly to web.config to retrieve settings. For each appSetting entry added to web.config we would add a corresponding property to the Configuration class.

Another advantage to this approach becomes apparent if we have an application setting that is not a string, but a date, integer, or other primitive type. In this case we could have the corresponding Configuration property parse the string from the web.config file and return the appropriate type.

You’ll notice we provided a read-only property for ConnectionInfo. The web.config file is not designed for constant updates. When an ASP.NET application launches a watch is put on the web.config file. ASP.NET will detect if the web.config changes while the application is running. When ASP.NET detects a change it will spin up a new version of the application with the new settings in effect. Any in process information, such as data kept in Session, Application, and Cache will be lost (assuming session state is InProc and not using a state server or database).


Friday, July 14, 2006

How to Enter Symbols into Window Forms or ASP.NET web pages

Letters with Accents

This list is organized by Accent type. To determine the appropriate numeric code, match the accent with the vowel.

Accent A E I O U Y
Grave
(Cap)
À
0192
È
0200
Ì
0204
Ò
0210
Ù
0217

Grave (Lower) à
0224
è
0232
ì
0236
ò
0242
ù
0249

Acute
(Cap)
Á
0193
É
0201
Í
0205
Ó
0211
Ú
0218
Ý
0221
Acute (Lower) á
0225
é
0233
í
0237
ó
0243
ú
0250
ý
0253
Circumflex
(Cap)
Â
0194
Ê
0202
Î
0206
Ô
0212
Û
0219

Circumflex (Lower) â
0226
ê
0234
î
0238
ô
0244
û
0251

Tilde
(Cap)
Ã
0195
-- Ñ
0209
Õ
0213
--
Tilde (Lower) ã
0227
-- ñ
0241
õ
0245
--
Umlaut
(Cap)
Ä
0196
Ë
0203
Ï
0207
Ö
0214
Ü
0220
Ÿ
0159
Umlaut (Lower) ä
0228
ë
0235
ï
0239
ö
0246
ü
0252
ÿ
0255

Example: To input the acute a á (0225), hold down the ALT key, type 0225 on the numeric keypad, then release the ALT key.

If you are having problems inputting these codes, please review the instructions for using the codes at the bottom of this Web page.

Other Foreign Characters

These include special punctuation and unique consonant and vowel symbols.

SYMBOL NAME CODE NUMBER
¡
Upside-down exclamation mark 0161
¿ Upside-down question mark 0191
Ç, ç French C cedille (caps/lowecase) 0199
0231
Œ,œ O-E ligature (caps/lowecase) 0140
0156
ß German Sharp/Double S 0223
Ø,ø Nordic O slash (caps/lowecase) 0216
0248
Å,å Nordic A ring (caps/lowecase), Angstrom sign 0197
0229
Æ, æ A-E ligature (caps/lowecase) 0198
0230
Þ, þ Icelandic/Old English Thorn (caps/lowecase) 0222
0254
Ð, ð Icelandic/Old English Eth (caps/lowecase) 0208
0240
« » Spanish/French quotation marks 0187
0171

Currency Symbols

SYMBOL NAME CODE NUMBER
¢ Cent sign 0162
£ British Pound 0163
€ Euro currency 0128
¥ Japanese Yen 0165
ƒ Dutch Florin 0131
¤ Generic currency symbol 0164


Math Symbols

SYMBOL NAME CODE NUMBER
÷ Division sign 0247
° Degree symbol 0176
¬ Not symbol 0172
± Plus/minus 0177
µ Micro 0181

Other Punctuation

These incude copyright symbols and special section marks.

SYMBOL NAME CODE NUMBER
© Copyright symbol 0169
® Registered symbol 0174
™ Trademark 0153
• List Dot 0149
§ Section Symbol 0167
– en-dash 0150
— em-dash 0151
Paragraph Symbol 0182

Using the Codes

Windows assigns a numeric code to different accented letters, other foreign characters and special mathematical symbols. For instance the code for lower case á is 0225, and the code for capital Á is 0193. The ALT key input is used to manually insert these letters and symbols by calling the numeric code assigned to them.

To use the codes:

  1. Place your cursor in the location where you wish to insert a special character.
  2. Activate the numeric key pad on the right of the keyboard by pressing Num Lock (upper right of keyboard). The Num Lock light on the keyboard will indicate that the numeric key pad is on.

    NOTE: You must use the numeric key pad; if you use the number keys on the top of the keyboard, the characters will not appear. If you are on a laptop or computer without a separate numeric keypad, other methods are recommended.
  3. While pressing down the ALT key, type the four-digit code on the numeric key pad at the right edge of the keyboard. The codes are "case sensitive." For instance, the code for lower-case á is ALT+0225, but capital Á is ALT+0193.

    NOTE: If you have the International keyboard activated, you will only be able to input codes with the ALT key on the left side of the keyboard.
  4. Release the ALT key. The character will appear when the ALT key is released.

    NOTE: You must include the initial zero in the code. For example to insert á (0225) you must type ALT+0225, NOT ALT+225.